2010-02-11 25 views
3

我有三個模型A,B和C,其中A has_many B; B belongs to CB has a created_on timestamp。 Ç的has_many A到B.Rails:使用模型has_many B belongs_to C return A其中B屬於C,B最近爲給定的A創建?

我想回到所有其中A具有歸屬於C與B,其中B是最近創建的B中,答

我可以用做方法循環。這可以單獨使用named_scopes嗎?或者是其他優雅/有效的方式嗎?根據對現實世界(TM)示例的請求,可以將A,B和C想象爲例如Pets(A),PetsName(B)和Names(C)。 PetsNames在特定時間給予寵物,並且任何給定的名字可以給予許多寵物。任何寵物都可以有許多名字(a:通過關係)。對於給定的名稱,我想所有的寵物,其中該名稱是該寵物最近創建的PetName。該呼叫可能看起來像@name.pets.most_recently_named_as

+0

硬盤使用A,B,C理解。嘗試編輯使用真正的名詞(即食譜,成分等)。我認爲你會是一個更好的迴應。 – Jonathan 2010-02-12 00:27:48

+0

我已經提供了一個真實世界的例子。 – Matt 2010-02-13 17:36:13

回答

4

Rails的方式來做到這一點是寵物的命名範圍。

事情是這樣的:

class Pets 
    has_many :pet_names 
    has_many :names, :through => :pet_names 

    named_scope :with_current_name, lambda {|name| 
    { :joins => "JOIN (pet_names pna, names) " + 
     "ON (pna.pet_id = pets.id AND pna.name_id = names.id) " + 
     "LEFT JOIN pet_names pnb " + 
     "ON (pnb.pet_id = pets.id AND pna.created_at < pnb.created_at)", 
     :conditions => ["pnb.id IS NULL AND names.id = ? ", name] 
    } 
    } 
end 

Pets.with_current_name(@name) 
@name.pets.with_current_name(@name) 

爲了保持命名爲中心的,你總是可以基於C定義的方法/名稱調用指定的範圍。

你總是可以做

class Name < ActiveRecord::Base 
    has_many :pet_names 
    has_many :pets, :through => :pet_names 

    def currently_named_pets 
    Pets.with_current_name(self) 
    end 
end 

而且

@name.currently_named_pets 

這是一個相當複雜的加入。這是一個指標,你應該應該重新考慮你存儲這些信息的方式。爲什麼名稱放在單獨的表格中如此重要?

你可能會更好做這樣的事情:

加入nameold_name列寵物後:

class Pet < ActiveRecord::Base 
    serialize :old_name, Array 
    def after_initialization 
    @old_name ||= [] 
    end 

    def name= new_name 
    self.old_name << new_name 
    self.name = new_name 
    end 

    named_scope :with_name, lambda {|name| 
    { :conditions => {:name => name}} 
    } 
end 
+0

非常感謝EmFi,我會嘗試命名的範圍。我知道這是一個複雜的連接,這就是爲什麼我問。這裏的大大簡化的例子只是我的真實模型的代理,它很好地獨立,我絕對不能使用序列化。獎勵點仍然在那裏用鏈接到A/Pet實例的方法進行。 – Matt 2010-02-14 00:09:31

+0

你能澄清你的意思嗎?從A/Pet的實例鏈接時涉及的操作是沒有意義的。 此外,你不想通過鏈式方法來做到這一點。語句之間的ActiveRecord開銷是非常低效的。但是,命名範圍仍然適用於返回「作爲/寵物」的關聯。 '@ store.pets.with_current_name(name)' – EmFi 2010-02-14 00:49:17

+0

你是對的!我的意思是C /名稱(如問題的原始大綱)。所以@ name.pets讓我把所有的寵物都叫做@name。我想鏈接一些東西,將寵物數組​​限制爲那些@name是最近名稱的地方(以保持方法名稱爲中心)。考慮到這一點,我認爲這是不可能完成的,所以你的解決方案似乎是要走的路。再次感謝您的幫助,並對混淆道歉。 – Matt 2010-02-14 02:45:37

相關問題