2010-02-05 153 views
51

考虑下面的AR模型,我想用户姓氏的字母顺序进行排序给出的句柄任务时:如何通过Ruby on Rails中的关联命令has_many?

我想获得一个任务,然后导航到其指定的用户,和排序用户名单按字母顺序排列

我一直在想,我应该能够在:order条款添加到has_many :users, :through => :assignments这样的:

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

然而,这是行不通的。

如何在给定任务时按last_name排序用户?

回答

7

这会为你工作吗?

# User.rb 

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

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

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

+2

不好意思碰到一个老问题,但这可能与未来的读者有关:一些插件(例如acts_as_list)不能用default_scope正常工作。 – robinjam 2011-05-08 14:56:37

+0

也碰到这个问题,因为我有类似的问题,但需要在通过表中的字段进行排序 - 真棒的是,default_scope也在通过表中工作,并且通过该关系检索的记录将遵守顺序。 – MBHNYC 2012-05-19 21:04:17

36

的Rails 3.x版:

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

UPDATE:Rails中3.X这仅适用于(之前也许是太)。对于4+,请参阅其他答案。

+0

对我来说工作得很好。作为第一个答案,干净的解决方案不会影响已排序模型的其他功能。 – barancw 2012-08-05 14:04:56

+2

不起作用,它说:订单不是关键。否认IS工作的答案。 – RohitPorwal 2014-06-30 09:57:08

12

M.G.Palmer's方法运作良好,但涉及表名称。有一种更好的方式来做到这一点:

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

但如果订单是由连接表确定的呢?例如任务... 但没有定义任务的默认范围.. – Tilo 2018-02-27 07:28:44

2

您还可以创建在分配表一个新的“排序顺序”列,并添加一个默认的范围,想

default_scope { order('sort_order desc')} 

到您的分配模式。

65

由于条件参数在轨道4,5过时,应该使用范围块:

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

它看起来像目前在Rails 4中有一个bug,这个https://github.com/rails/rails/issues/17904“在Rails 4.0中, order子句被忽略,在Rails 4.1中,生成了无效的SQL。“ – Nate 2014-12-29 13:35:13

+0

它甚至没有给我,只是完全忽略了没有消息的订单条款。 – 2016-08-03 18:04:47

6

这对我的作品(Rails的4.2)

通过地图上的应用排序不保留,又名这是不够的,有流派下令:

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 

要对分配的工作,这应该是这样的(未经测试)

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 
2

我使用Rails(5.0.0.1),并可以使排序与此语法在我的模型组,有许多用户透过group_users:

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

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

相关问题