2008-10-20 61 views
2

比方說,我有以下代碼:給定一組ActiveRecord對象,我可以通過方法調用輕鬆收集它們的關係嗎?

@sites = Site.find(session[:sites]) # will be an array of Site ids 
@languages = Language.for_sites(@sites) 

for_sites是在返回與這些網站相關的語言的語言模型named_scope和語言通過利用的has_many站點關聯。目標是使@語言具有與網站相關的各種語言。

與其說在第二行的語言對象的,我非常喜歡說

@sites.languages 

,並具有相同的列表退還給我。有沒有辦法在Rails 2.1(或邊緣)中乾淨地做到這一點?我知道關聯和命名範圍可以擴展數組對象的屬性,但除非我錯過了某些不適用的東西。這樣做的任何插件都會受到歡迎,它並不一定是核心。

回答

3

您可以擴展由Site.find返回的數組。

class Site 
    def find(*args) 
    result = super 
    result.extend LanguageAggregator if Array === result 
    result 
    end 
end 

module LanguageAggregator 
    def languages 
    Language.find(:all, :conditions => [ 'id in (?)', self.collect { |site| site.id } ]) 
    end 
end 
+0

啊,所以這是其他方法如何做...謝謝,這絕對是最接近的,甚至看起來像它可以被提取出來的模塊和/或插件。 – 2008-10-23 23:12:25

0

您的實例變量@sites是一個Array對象,而不是Site,所以我不認爲可以使用named_scope。你可以打開Array類來達到這種效果,但(亞克西)

class Array 

    def languages 
    ... 
    end 

end 
+0

對,我知道Rails以可擴展的方式爲某些其他對象(例如從has_many關聯返回的數組)。我希望會有更清潔的東西。謝謝你的回答! – 2008-10-21 15:35:05

0

如果添加了has_manyhas_and_belongs_to_many鏈接語言的網站,那麼你可以使用一個包含與做這樣的事情:

Site.find(:all, :conditions =>{:id => session[:sites]}, :include => :languages) 

您可以創建一個名爲範圍做:ID =>會話[:網站]的東西,如:

class Site 
    named_scope :for_ids, lambda{ |x| {:conditions => {:id => x } 
end 

,然後做

Site.for_ids(session[:sites]).find(:all, :include => :languages) 

希望這給你一些想法

+0

我知道我可以:包括=>語言,但這並不完全符合我的要求 - 我基本上正在尋找一系列網站的語言列表。 find([array of id])已經返回這些網站,所以我認爲這對我來說不是什麼好處......謝謝你的回答! – 2008-10-21 15:37:19

2

爲什麼不使用兩個named_scopes?

class Site 
    named_scope :sites, lambda{|ids| :conditions => "id in (#{ids.join(',')})"} 
    named_scope :languages, :include => :languages ... (whatever your named scope does) 
end 

電話:

Site.sites(session[:sites]).languages 

,或者,如果你想語言對象後面

Site.sites(session[:sites]).languages.collect{|site| site.languages}.flatten 

你也可以做直接的語言對象。 我用:加入由於Rails 2.1分裂並:包括爲兩個查詢,這意味着我們不能在使用場所:條件

class Language 
    named_scope :for_sites, lambda{|site_ids| :joins => 'inner join sites on languages.site_id = sites.id' :conditions => "sites.id in (#{site_ids.join(',')})"} 
end 

電話:

Language.for_sites(session[:sites]) 

在這兩個例子我我們假設session [:sites]完全由你控制,而不受SQL注入的限制。如果沒有,請確保您處理清理ID的

+0

你的第二次嘗試實際上是非常接近的(只需要一個.uniq調用),但我有點希望能夠得到一些好的Ruby Fresh感覺的語法糖。你的語言想法基本上就是我現在的想法,雖然略有不同,因爲我有一個site_language模型。雖然謝謝! – 2008-10-21 15:56:40

相關問題