簡體   English   中英

Arel Aggregations,Count,Outer Join?

[英]Arel Aggregations, Count, Outer Join?

我有一個Fact模型,其中has_many :votes 投票還有一個user_id字段。 我想在Fact模型的范圍內表達以下內容:給我所有有0票且user_id等於X的事實。

我對Arel不太熟悉,無法理解如何解決這個問題。 想法?

這有效:

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范圍在幕后使用Arel - http://m.onkey.org/active-record-query-interface

我最終用以下范圍解決了這個問題:

  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])}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM