Рельсы 5: ActiveRecord или запрос


как сделать or запрос рельсы 5 ActiveRecord? Кроме того, можно ли цепочку or с where в запросах ActiveRecord?

4 90

4 ответа:

возможность цепочки or п. вместе с where в пункте ActiveRecord запрос будет доступен в рельсы 5. Смотрите связанное Обсуждение и запрос на вытягивание.

таким образом, Вы сможете сделать следующие вещи в рельсы 5:

и post С id 1 или 2:

Post.where('id = 1').or(Post.where('id = 2'))

другие примеры:

(A && B) || C:

    Post.where(a).where(b).or(Post.where(c))

(A/ / B) & & C:

    Post.where(a).or(Post.where(b)).where(c)

нам не нужно ждать рельсы 5, чтобы использовать это OR запрос. Мы также можем использовать его с rails 4.2.3. Есть обратный порт здесь.

спасибо Эрик-Го для где-либо, теперь мы можем добавить этот OR функциональные возможности >= rails 4.2.3 также, используя этот камень.

мне нужно было сделать (A && B) || (C && D) || (E && F)

но в Rails 5.1.4текущее состояние этого get слишком сложно выполнить с помощью Arel или-chain. Но я все еще хотел использовать Rails для создания как можно большей части запроса.

поэтому я сделал небольшой хак:

в моей модели я создал частная метод sql_where:

private
  def self.sql_where(*args)
    sql = self.unscoped.where(*args).to_sql
    match = sql.match(/WHERE\s(.*)$/)
    "(#{match[1]})"
  end

далее в моей области я создал массив для хранения Или это

scope :whatever, -> {
  ors = []

  ors << sql_where(A, B)
  ors << sql_where(C, D)
  ors << sql_where(E, F)

  # Now just combine the stumps:
  where(ors.join(' OR '))
}

что приведет к ожидаемому результату запроса: SELECT * FROM `models` WHERE ((A AND B) OR (C AND D) OR (E AND F)).

и теперь я могу легко комбинировать его с другими областями и т. д. без каких-либо противоправных или с.

красота в том, что мой sql_where принимает нормальные аргументы where-clause: sql_where(name: 'John', role: 'admin') будет генерировать (name = 'John' AND role = 'admin').

(только как дополнение к ответу на Rakibul К М в Исламе.)

через области, код может стать красивее (в зависимости от глаза):

scope a,      -> { where(a) }
scope b,      -> { where(b) }

scope a_or_b, -> { a.or(b) }