2010-02-05 108 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 

調整代碼,以您的需要,將工作。

相關問題