SQL OR в областях применения в Rails 3 / Arel - PullRequest
1 голос
/ 16 марта 2011

Я пытаюсь создать область действия модели Rails 3, которая, по сути:

scope :published, where(:published => true)

scope :viewable_by, lambda { |user| where(:user_id => user.id).or(published) }

Проблема в том, что я не могу найти способ заставить эту работу.

Я надеялся, что arel_table сработает, но он жалуется на то, что "Невозможно посетить ActiveRecord :: Relation":

where(arel_table[:user_id].eq(user.id)).or(published)

Это может быть сделано путем репликации "опубликованного" контекста как Arel, но тогда я буду повторять код(и в моем проекте «опубликованная» область действия более глубока).

Лучшее, что я могу придумать, это:

scope :viewable_by, lambda { |user| where("(user_id = ?) OR (#{published.where_values.collect(&:to_sql).join(" AND ")})", user.id) }

1 Ответ

0 голосов
/ 16 марта 2011

Это самое короткое, что я мог придумать после небольшой копки:

scope :published, where(:published => true)
scope :viewable_by, lambda { |user| where("user_id = ? OR #{published.where_clauses.first}", user.id) }

(Конечно, это работает только с одним предложением where; используйте join, если их больше одного.)

Я бы порекомендовал использовать драгоценный камень, такой как MetaWhere , который более четко раскрывает некоторые из подкреплений Арела.Вот пример с главной страницы, на которую ссылаются выше, которая создает запрос OR:

Article.where(:title.matches % 'Hello%' | :title.matches % 'Goodbye%').to_sql
 => SELECT "articles".* FROM "articles" WHERE (("articles"."title" LIKE 'Hello%'
    OR "articles"."title" LIKE 'Goodbye%'))
...