如何通过Ruby on Rails中的关联来订购has_many?

鉴于以下AR模型,我想在给予任务句柄时按姓氏的字母顺序对用户进行sorting:

#user has_many :assignments has_many :tasks, :through => :assignments #assignment belongs_to :task belongs_to :user #task has_many :assignments has_many :users, :through => :assignments 

我想得到一个任务,然后导航到其分配的用户, 并按字母顺序sorting用户列表

我一直在想,我应该能够将:order子句添加到has_many :users, :through => :assignments像这样:

 #task.rb has_many :assignments has_many :users, :through => :assignments, :order => 'last_name, first_name' 

然而这是行不通的。

在给定任务时,如何按last_namesorting用户?

由于条件参数在Rails 4中已被弃用,所以应该使用范围块:

 has_many :users, -> { order 'users.last_name, users.first_name' }, :through => :assignments 

Rails 3.x版本:

 has_many :users, :through => :assignments, :order => 'users.last_name, users.first_name' 

更新:这只适用于Rails 3.x(也许在此之前)。 对于4+,请参阅其他答案。

MGPalmer's方法运作良好,但涉及表名。 有一个更好的方法来做到这一点:

 has_many :users, :through => :assignments, :order => [ :last_name, :first_name ] 

这会为你工作吗?

 # User.rb class User < ActiveRecord::Base default_scope :order => 'last_name ASC' ... end 

您可以定义其他命名范围,以便sorting时需要不同。

http://ryandaigle.com/articles/2008/11/18/what-s-new-in-edge-rails-default-scoping

这对我有用(Rails 4.2)

在直通地图上应用sorting不会被保留下来,也就是说这还不足以让stream派sorting:

 has_many :disk_genre_maps, -> {order('disk_genre_map.sort_order')}, :inverse_of => :disk, :dependent => :destroy, :autosave => true has_many :genres, # not sorted like disk_genre_maps :through => :disk_genre_maps, :source => :genre, :autosave => true 

所以我覆盖这个每个实例:

 def genres # redefine genres per instance so that the ordering is preserved self.disk_genre_maps.map{|dgm|dgm.genre} end 

为了完成任务,这应该是这样的(未经testing)

 def genres= some_genres self.disk_genre_maps = some_genres.map.with_index do |genre, index| DiskGenreMap.new(disk:self, genre:genre, sort_order:index) end end 

您也可以在赋值表上创build一个新的“sort_order”列,并添加一个默认的作用域

 default_scope { order('sort_order desc')} 

到你的作业模型。

我正在使用Rails(5.0.0.1),并可以在我的模型组中使用这个sintaxe进行sorting,通过group_users有许多用户:

 # Associations. has_many :group_users has_many :users, -> { order(:name) }, through: :group_users 

调整代码,以适应您的需要,将工作。