Арельские объединения, граф, внешнее объединение? - PullRequest
3 голосов
/ 08 ноября 2010

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

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

Ответы [ 2 ]

1 голос
/ 19 ноября 2010

Я решил эту проблему в следующей области:

  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 голос
/ 14 ноября 2010

Это работает:

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)

Область voice_count немного квадратная, но вы можете связать эти искатели так, как вам нравится, вы также можете увидеть базовый 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)

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

...