In some applications we have cases where a many_to_many association is ranked in one of the sides. Say a user has a list of preferred songs, or a document has a weight for a keyword. How should I implement this? Scopes are not, I believe, dynamical enough for this.
With more detail, it seems there are two different cases:
A "weight" or "tag" that could be searched with
user.songs.where( tag: "five stars")
an order, integer, which could perhaps be better with an overload of []:
users.songs[3]
Our current workaround is to create directly in the join_table of the through, and fill it with fake records so that a sort will allow us to use the [] notation even if the record does not exist. In a next step we can avoid this filling with the overload of [] in the join table:
has_many :user_songs, -> {order "position ASC" } do
def [](pos)
...
And surely we could also do the same overload in has_many: songs through user_songs
but the real problem (the "Feature request") is an implementation of Create.
We would like something as
user.songs.create( position: 3)
or
mysong=song.create()
user.songs<< (mysong, tag: "five stars")
A subtle detail, that distinguises the "order" from the "tag" is that in the later case the collection is still a has_many, with multiple records having the same rank. In this case it looks very much an scope, except that it is not fixed. The former case, on the other hand, transform the has_many in an "indexed has_one".