rom-sql
rom-sql copied to clipboard
Need to override combine_keys with whatever in order to combine result correctly
Using the gist provided below, ROM doesn't combine buildings correctly. The query result is empty even though the SQL query was correct.
[
#<ROM::Struct::User id=1 login="[email protected]" employee_id=5 buildings=[]>
]
However, if you will modify the association
has_many :buildings, override: true, view: :for_user
and override combine_keys with literally whatever:
has_many :buildings, override: true, view: :for_user, combine_keys: {blah: :blah} # combine_keys: {} is also fine
it will work:
[
#<ROM::Struct::User id=1 login="[email protected]" employee_id=5
buildings=[#<ROM::Struct::Building id=1 name="wew">, #<ROM::Struct::Building id=2 name="weeew">]>
]
Gist to reproduce:
rom = ROM.container(:sql, 'sqlite::memory') do |conf|
conf.gateways[:default].use_logger(Logger.new($stdout))
conf.default.create_table(:users) do
primary_key :id
column :login, String
end
conf.default.create_table(:employees) do
primary_key :id
column :name, String, null: false
end
conf.default.create_table(:buildings_employees) do
foreign_key :building_id, :buildings
foreign_key :employee_id, :employees
end
conf.default.create_table(:buildings) do
primary_key :id
column :name, String, null: false
end
conf.default.create_table(:employees_users) do
foreign_key :verifable_id, :employees
foreign_key :user_id, :users
end
conf.relation(:users) do
schema(:users, infer: true) do
associations do
has_many :employees_users
has_many :users, through: :employees_users
has_many :buildings, override: true, view: :for_user
end
end
end
conf.relation(:employees) do
schema(:employees, infer: true) do
associations do
end
end
end
conf.relation(:buildings) do
schema(:buildings, infer: true) do
associations do
has_many :buildings_employees
end
end
def for_user(_assoc, users)
join(:buildings_employees)
.where(employee_id: users.pluck(:employee_id))
end
end
conf.relation(:buildings_employees) do
schema(:buildings_employees, infer: true) do
associations do
belongs_to :building
belongs_to :employee
end
end
end
conf.relation(:employees_users) do
schema(:employees_users, infer: true) do
associations do
belongs_to :user, foreign_key: :user_id
belongs_to :employee, foreign_key: :verifable_id
end
end
end
end
class UserRepo < ROM::Repository[:users]
def by_id(id)
users
.join(:employees_users)
.join(:employees, { id: :verifable_id })
.select_append { |r| r[:employees][:id].as(:employee_id) }
.combine(:buildings)
.to_a
end
end
employee = rom.relations[:employees].changeset(:create, name: 'Jane', id: 5).commit
rom.relations[:employees].changeset(:create, name: 'Jane', id: 8).commit
user = rom.relations[:users]
.changeset(:create, login: '[email protected]')
.commit
rom.relations[:employees_users]
.changeset(:create, user_id: user[:id], verifable_id: employee[:id]).commit
au = rom.relations[:buildings]
.changeset(:create, employee_id: employee[:id], name: 'wew').commit
au2 = rom.relations[:buildings]
.changeset(:create, name: 'weeew').commit
rom.relations[:buildings_employees].changeset(
:create,
[
{ employee_id: employee[:id], building_id: au[:id] },
{ employee_id: employee[:id], building_id: au2[:id] }
]
).commit
repo = UserRepo.new(rom)
user = repo.by_id(1)
Bundled with: rom-sql (2.3.0)