рельсы 3 - или области - PullRequest
       14

рельсы 3 - или области

2 голосов
/ 26 июля 2011

Мы обновляем приложение rails 2.Мы с радостью использовали fake_arel , который обеспечивает очень хороший "или" охват.

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

У нас есть такой код:

scope.or(Event.horse, Event.dog, Event.trap).today

Модель выглядит следующим образом:

class Event < ActiveRecord::Base
 named_scope :horse, lambda { {:conditions => ["sport_category_id in (?)", SportCategory.find_horse_ids] }}
 named_scope :dog, lambda { {:conditions => ["sport_category_id in (?)", SportCategory.find_dog_ids] }}
 named_scope :trap, lambda { {:conditions => ["sport_category_id in (?)", SportCategory.find_trap_ids] }}
end

Эти области должны быть отдельными и использоваться повсеместно.Эта модель на самом деле имеет десятки областей видимости, которые используются в комбинации, поэтому переписать все это - последнее, что мы хотим сделать.

Кажется странным, что вы не можете 'или' определять области вместе.

Может кто-нибудь предложить такой же способ сделать это в Rails 3?Даже используя арель, я не вижу, как это сделать.Мы используем meta_where в другом проекте, но он также не предлагает ничего подобного.

Ответы [ 3 ]

1 голос
/ 26 июля 2011

Что ж, способ сделать это в вашей модели (адаптировать его к вашим потребностям!):

where(:event => ['horse', 'dog', 'trap'])

Массив создаст оператор IN, что вам и нужно.Кроме того, вы можете использовать рельсы 3 прицела для достижения этого:

scope :my_scope, where(:event => ['horse', 'dog', 'trap'])

Тогда вы можете использовать это следующим образом:

mymodel.my_scope # and possibility to chain, like :
mymodel.my_scope.where(:public => true)
0 голосов
/ 05 января 2012

Мне не удалось получить код от Github-gist от работающего Фила, но это вдохновило меня придумать следующее, которое, я думаю, является более простым решением.Он использует метод класса, который, тем не менее, возвращает класс ActiveRecord :: Relation.

def self.or alt_scope
  either = scoped.where_clauses.join(' AND ') 
  alternative = alt_scope.where_clauses.join(' AND ')

  Locatie.unscoped.where("(#{either}) OR (#{alternative})").
    joins(scoped.joins_values).joins(alt_scope.joins_values).
    group(scoped.group_values).group(alt_scope.group_values).
    having(scoped.having_values).having(alt_scope.having_values).
    includes(scoped.includes_values).includes(alt_scope.includes_values).
    order(scoped.order_values).order(alt_scope.order_values).
    select(scoped.select_values).select(alt_scope.select_values)
end

Просто добавьте это в свой класс.Затем вы получите возможность создавать множественные ИЛИ-запросы следующим образом:

Event.horse.or(Event.dog).or(Event.trap)

, которые вы можете впоследствии «хранить» в области:

scope :horse_dog_or_trap, horse.or(Event.dog).or(Event.trap)

, а также расширять областьеще дальше, например:

Event.horse.or(Event.dog).or(Event.trap).today
0 голосов
/ 18 августа 2011

Я извлек функцию 'or' из fake_arel и заставил ее работать с рельсами 3.0x (не уверен, будет ли она работать с 3.1, поскольку мы не используем это здесь)

В случае, если кто-то заинтересован, я положил его в гист :

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...