Hi,
In our project we are overriding relation associations with custom views.
For several reasons (principally many-to-many associations, and multi-table inheritance) we have lots of intermediary tables, which means our codebase has lots of examples of chained method calls on entities:
user.user_groups.first.group.admin
In the case of many-to-many associations, we do make use of ROM’s through: functionality, but often we need to access attributes that exist on the intermediary table. through: also does not seems to work in the case of belongs_to associations. What we were hoping to do was use views with override: true and select_append the attributes of the intermediary table we want onto the target table. Something roughly along these lines:
class Users < ROM::Relation[:sql]
schema(infer: true) do
associations do
has_many :user_groups
has_many :groups, override: true, view: for_users
end
end
end
class UserGroups < ROM::Relation[:sql]
schema(infer: true) do
associations do
belongs_to :user
belongs_to :group
end
end
end
class Groups < ROM::Relation[:sql]
schema(infer: true) do
associations do
has_many :user_groups
end
end
def for_users(_assoc, users)
user_ids = users.pluck(:id)
join(:user_groups)
.where(self[:user_id] => user_ids)
.select_append { |user_groups:| user_groups[:admin].as(:admin) }
end
end
Which would allow for a more succinct:
user.groups.first.admin
The issue we are running into is that attributes that are appended in the view, with
override: true are stripped away. This looks to be intended functionality within ROM to remove the join keys.
We have several questions around this.
Firstly, is there a way that we can select_append within views with override: true that we are missing?
Secondly, if not, are there any plans to add this functionality to future releases of ROM?
Lastly, if the answer to both the above are no, would you be open to pull requests that allow for this?
Thanks in advance,
Charlie