2012-07-03 66 views
0

如果我有以下類利用協會,如示波器

class User 
    has_many :documents 
end 

class Document 
    belongs_to :user 
end 

我想能夠做到以下

User.where("id > 200").documents 

應生成SQL像

select * from documents 
join users on documents.user_id == users.id 
where users.id > 200 

但主動記錄不是那麼聰明。這是一個不合理的事情,希望可以開箱即用嗎?

==一個可能的反解燥==

class User 
    has_many :documents 
    def self.documents 
     Documents.joins(:users).merge(self.scoped) 
    end 
end 

但這不是因爲它似乎複製我 已定義的關係非常乾燥。

回答

0

試試這個:

Document.joins(:user).where('user.id > ?', 200) 
+0

這會返回用戶不是文檔。 – bradgonesurfing

+0

@bradgonesurfing所以你可以扭轉它。我想念你的SQL。 – xdazz

+0

一個更復雜的例子。 Cities.where([「name like'%me%'])。inhabitants.where([」id> 200「])。 – bradgonesurfing

1

不,你不能做到這一點與ActiveRecord的。 經驗法則 - 開始調用方法的類是返回對象的類。所以做User.whatever總是會返回User對象。這幾乎消除了做你想做的事情的可能性。

如果您想獲取Document對象,則需要在Document類上開始查詢它們。您始終可以在User模型中定義用戶特定的作用域,併爲了DRY而在文檔模型中重用它們。

class User < ActiveRecord::Base 
    scope :foo, where("users.id > 200") 
end 

class Document < ActiveRecord::Base 
    belongs_to :user 

    scope :bar, joins(:user).merge(User.foo) 
end 

這可以有效地讓您在文檔模型中使用User(和用戶特定)中定義的範圍。我還會聲稱在User.where(「id> 200」)。文檔比Document.where(「users.id> 200」)(有意跳過的連接)更有意義。

所以我個人認爲你只是試圖從錯誤的一端:)

+0

我明白,默認情況下我不能做到這一點,但是做到這一點的信息在那裏,關聯邏輯被編碼在has_many聲明中,這可以讓你從單個實例對象到一個不同類型的對象的集合我想知道是否有一些基本的東西可以阻止你通過has_many關係從一個類型的集合(活動關係)到另一個類型的集合遍歷 – bradgonesurfing

+0

如果不檢查代碼,我會說,「經驗法則 - 你開始調用方法的類是返回對象所在的類」,這是基本問題之一。代碼需要相當多的變化t o使它足夠聰明,能夠解析AR :: Relation的最後一個關係並將其用作對象類型。即使那樣我也會不同意,因爲這會妨礙可讀性。 User.foo清楚地顯示你得到的回報。 User.documents.with_foo。pages.filled.lines.bold_and_italic.letters.bar不會:) –

0

對於示例類處理這個問題,你可以查詢在documentsuser_id領域:

Document.where("user_id > 200")