Rails: How to sort many-to-many relation

蹲街弑〆低调 提交于 2019-12-02 20:51:01

问题


I have a many-to-many relationship between a model User and Picture. These are linked by a join table called Picturization.

If I obtain a list of users of a single picture, i.e. picture.users -> how can I ensure that the result obtained is sorted by either creation of the Picturization row (i.e. the order at which a picture was associated to a user). How would this change if I wanted to obtain this in order of modification?

Thanks!

Edit Maybe something like

picture.users.where(:order => "created_at")
  • but this created_at refers to the created_at in picturization

回答1:


Have an additional column something like sequence in picturization table and define sort order as default scope in your Picturization

default_scope :order => 'sequence ASC'

If you want default sort order based on modified_at then use following default scope

default_scope :order => 'modified_at DESC'



回答2:


You can specify the table name in the order method/clause:

picture.users.order("picturizations.created_at DESC")



回答3:


Well, in my case, I need to sort many-to-many relation by a column named weight in the middle-table. After hours of trying, I figured out two solutions to sort many-to-many relation.

Solution1: In Rails Way

picture.users.where(:order => "created_at")

cannot return a ActiveRecord::Relation sorted by Picturization's created_at column.

I have tried to rewrite a default_scope method in Picturization, but it does not work:

def self.default_scope
  return Picturization.all.order(weight: :desc)
end  

Instead, first, you need to get the ids of sorted Picturization:

ids = Picturization.where(user_id:user.id).order(created_at: :desc).ids

Then, you can get the sorted objects by using MySQL field functin

picture.users.order("field(picturizations.id, #{ids.join(",")})")

which generates SQL looks like this:

SELECT `users`.* 
FROM `pictures` INNER JOIN `picturizations` 
ON `pictures`.`id` = `picturizations`.`picture_id` 
WHERE `picturizations`.`user_id = 1#for instance 
ORDER BY field(picturizations.id, 9,18,6,8,7)#for instance

Solution2: In raw SQL Way

you can get the answer directly by using an order by function:

SELECT `users`.* 
FROM `pictures` INNER JOIN `picturizations` 
ON `pictures`.`id` = `picturizations`.`picture_id` 
WHERE `picturizations`.`user_id = 1

order by picturizations.created_at desc


来源:https://stackoverflow.com/questions/10417901/rails-how-to-sort-many-to-many-relation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!