Ruby on rails Arel聚合、计数、外部联接?
我有一个Ruby on rails Arel聚合、计数、外部联接?,ruby-on-rails,ruby,ruby-on-rails-3,arel,Ruby On Rails,Ruby,Ruby On Rails 3,Arel,我有一个事实模型,有很多:投票。投票还有一个user\u id字段。 我想在事实模型的范围内表达以下内容:给我所有的事实,这些事实有0个投票权,并且用户id等于X 我对阿雷尔不太熟悉,不知道该如何应对。想法?这项工作: class Fact < ActiveRecord::Base scope :by_user, lambda { |id| joins(:user).where('users.id == ?', id).readonly(false) } scope :vot
事实
模型,有很多
:投票
。投票还有一个user\u id
字段。
我想在事实
模型的范围内表达以下内容:给我所有的事实,这些事实有0个投票权,并且用户id
等于X
我对阿雷尔不太熟悉,不知道该如何应对。想法?这项工作:
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)
在您的评论之后,您可以在纯阿雷尔中也这样做,首先声明关系:
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\u id].eq(1)
然后使用它:
Fact.find_by_sql(sql)
我相信,为了获得更优雅的语法(没有“where 0==…”),您还可以做很多事情。另外,我非常确定Rails3作用域在幕后使用Arel-我最终用以下作用域解决了这个问题:
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])}
阿雷尔是什么?你能发个链接吗?@Sam:是的,这和我现在做的差不多;我的问题是如何使用Arel,或者至少是主动关系来实现这一点。此外,作为一种诡辩,本场景中描述的user_id字段属于投票模型。
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])}