如何使用ActiveRecord对深层嵌套集合进行排序?
问题描述:
我正在构建一个音乐管理Rails应用程序,我的应用程序的用户将能够制作专辑的有序播放列表,并且每个专辑都会有一个有序的歌曲列表。如何使用ActiveRecord对深层嵌套集合进行排序?
在本质上,这将是这样的:
class User < ActiveRecord::Base
has_many :playlists, :order => "position"
has_many :albums, :through => :playlists
end
class Playlist < ActiveRecord::Base
belongs_to :user
belongs_to :album
end
class Album < ActiveRecord::Base
has_many :songs, :order => "position"
has_many :playlists
end
class Song < ActiveRecord::Base
belongs_to :album
end
(我使用acts_as_list
使用的歌曲和播放列表表一position
列来管理歌曲和播放列表的排序顺序,分别。)
现在我想查找给定用户的所有歌曲(按顺序)的列表。如果我这个范围内添加到宋型号:
scope :for_user, lambda{|user|
joins(:album => {:playlists => :user}).
where(:'users.id' => user.id)
}
我可以做到这一点,但返回的记录没有保持秩序。相反,我希望看到每首歌曲首先按专辑的播放列表位置排序,然后按该歌曲在该专辑中的位置排序。换句话说,如果用户想按顺序播放专辑A,B和C,我正在查找来自A的所有歌曲(按照他们在专辑中的顺序)以及来自B的所有歌曲(按顺序),加上C中的所有歌曲(按顺序)。
我试过的为了和组条款的范围若干排列,但没有已订购专辑的范围内订购歌曲的预期效果。
答
你尝试过:
scope :for_user, lambda{|user|
joins(:album => {:playlists => :user}).
where('users.id' => user.id).
order('"albums"."position" ASC, "songs"."position" ASC')
}
的ORDER BY子句中的SQL接受多个参数(见http://www.quackit.com/sql/tutorial/sql_order_by.cfm)。不要使用GROUP BY,产生聚集(如http://www.w3schools.com/sql/sql_groupby.asp)
答
时要添加到m_x的答案,如果你希望你的代码将被更多的面向对象是唯一有用的,你可以建立订单条款是这样的:
order(Album.arel_table[:position], Song.arel_table[:position])