Rails: How to sort many-to-many relation

前端 未结 3 648
攒了一身酷
攒了一身酷 2021-01-29 04:10

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 pict

3条回答
  •  北海茫月
    2021-01-29 05:16

    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
    

提交回复
热议问题