2009-07-15 59 views
1

我有一個結構是這樣的:Rails的活動記錄:找到會同:訂單和:

class User 
    has_many :dongles 
    has_many :licences, :through => :dongles 
end 

class Dongle 
    has_many :licences 
    belongs_to :user 
end 

class Licence 
    belongs_to :dongle 
end 

然而,時間的推移和用戶最終獲得多份許可證爲每個適配器。合理的,該應用程序想要總結每個最新的許可證。

我知道我能天真地做這樣的:

user.dongles.each do |dongle| 
    licence = dongle.licences.find(:first, :order => 'created_at DESC') 
    # do something with the licence info 
end 

但是,有沒有辦法通過收集來做到這一點,避免了大量的查詢,這通常通過做它用簡單的方式造成的?

我嘗試這樣做:

user.licences.find(:all, :order => 'created_at DESC', :group => 'dongle_id') 

這確實返回一個許可證爲每個加密狗,但第一個需要被「身份證」決定,由順序我已經在查詢中指定。

有沒有一種方法,我可以把它給我的第一各自的,使用排序我提供,以決定這是第一個?

回答

3

從您的模型中,所有關聯信息已經被聲明。通過使用ActiveRecord 包括選項執行單個查詢,您實際上可以使用每個用戶訪問加密狗和許可證信息。

# Say the table name is licences and dongles. 
users = User.find(:all, 
    :include => [:dongles, :licences], 
    :order => "licences.created_at DESC, dongles.created_at DESC") 

我假設你想創建每個用戶擁有的每個加密狗的最新許可證摘要。你可以根據自己的實際需要來切斷循環。

users.each do |user| 
    # do something with your user info 
    user.dongles.each do |dongle| 
    # do something with your dongle info 
    licence = dongle.licences.first 
    # do something with the licence info 
    end 
end 

瞭解更多關於這個在http://snippets.dzone.com/posts/show/2089

+0

這是一件好事,因爲它確實減少了查詢的數量,而該代碼是不是從我已經有了很大的不同(這是反正更可讀。) – Trejkaz 2009-07-17 06:48:22

-1

您是否嘗試過用默認的範圍是什麼? 首先,您可以嘗試在has_many中添加訂單,如我在用戶中所示。

class User 
    has_many :dongles 
    has_many :licences, :through => :dongles, :order => 'created_at DESC' 
end 

不過,我不知道如果這實際上與具有一對多,通過協會的工作,也許,如果不工作,你可以嘗試將其添加到該協會的適配器來代替。

class Dongle 
    has_many :licences, :order => 'created_at DESC' 
    belongs_to :user 
end 

第二種選擇是嘗試使用默認範圍,如我在許可證中顯示的那樣。

class Licence 
    default_scope :order => 'created_at DESC' 
    belongs_to :dongle 
end 

之後,它應該是不夠的,只是用得到它user.licenses.find(:first)