2010-11-08 68 views
3

我有一個Fact模型,其中has_many:votes。投票也有一個user_id字段。 我想表達的範圍爲Fact模型如下:給我這有0票用user_id等於XArel Aggregations,Count,Outer Join?

所有事實我不太有足夠阿雷爾熟悉明白,我怎麼可能解決這個問題。想法?

+0

是什麼AREL?你能發佈一個鏈接嗎? – s84 2010-11-08 05:45:29

+0

@Sam:http://stackoverflow.com/questions/2770415/what-exactly-is-arel-in-rails-3-0 – Zabba 2010-11-08 05:55:16

回答

1

我結束了以下範圍內解決這個問題:

scope :not_voted_on_by_user, lambda {|user_id| select("distinct `facts`.*").joins("LEFT JOIN `votes` ON `facts`.id = `votes`.fact_id").where(["votes.user_id != ? OR votes.user_id IS NULL",user_id])} 
1

這工作:

class Fact < ActiveRecord::Base 
    scope :by_user, lambda { |id| joins(:user).where('users.id == ?', id).readonly(false) } 
    scope :vote_count, lambda { |count| where('? == (select count(fact_id) from votes where votes.fact_id == facts.id)', count)} 
end 

Fact.by_user(1).vote_count(0) 

的vote_count範圍是有點sqly但你可以鏈這些發現者,只要你喜歡,你還可以看到底層的SQL用:

Fact.by_user(1).vote_count(0).to_sql 

,並進一步你的意見,你可能會在純Arel中做同樣的事情,首先宣佈關係:

f = Arel::Table.new(:facts) 
v = Arel::Table.new(:votes) 
u = Arel::Table.new(:users) 

然後編寫查詢並將其呈現給sql。

sql = f.join(u).on(f[:user_id].eq(1)).where('0 == (select count(fact_id) from votes where votes.fact_id == facts.id)').to_sql 

您可以在列行爲與運營商:f[:user_id].eq(1)

然後使用它:

Fact.find_by_sql(sql) 

我敢肯定,那裏有很多更是你可以做的就是更優雅語法(沒有'where 0 == ...')。此外,我敢肯定Rails3中範圍使用阿雷爾幕後 - http://m.onkey.org/active-record-query-interface

+0

是的,這與我現在所做的相似;我的問題是如何使用Arel來做到這一點,或者至少是積極的關係。另外,作爲一個詭計,本場景中描述的user_id字段屬於Vote模型。 – 2010-11-18 05:00:25