2010-11-08 1 views
3

У меня есть модель Fact, которая has_many:votes. Голоса также имеют поле user_id. Я хотел бы выразить следующее в рамках для Fact модели: Дай мне все факты, которые имеют 0 голосов с user_id равного X.Агрегация Ареля, граф, внешняя связь?

Я не вполне достаточно знаком с Arel, чтобы понять, как я мог бы справиться с этим. Идеи?

+0

что Арел? можете ли вы опубликовать ссылку? – s84

+0

@Sam: http://stackoverflow.com/questions/2770415/what-exactly-is-arel-in-rails-3-0 – Zabba

ответ

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 

и в дальнейшем ваш комментарий, вы можете сделать то же самое в чистом Ареле, сначала объявив Отношения:

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) 

Я уверен, Theres намного больше, что вы могли бы сделать, чтобы получить более элегантный синтаксис (без «где 0 == ...»). Кроме того, я уверен, что Rails3 прицелы использовать Arel за кулисами - http://m.onkey.org/active-record-query-interface

+0

Да, это похоже на то, что я делаю сейчас; мой вопрос заключается в том, как сделать это с помощью Arel или, по крайней мере, активного отношения. Кроме того, в качестве поворота поле user_id, описанное в этом сценарии, относится к модели Vote. –

 Смежные вопросы

  • Нет связанных вопросов^_^