2010-11-08 32 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