it-swarm.com.ru

Rails 5: ActiveRecord OR запрос

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

100
K M Rakibul Islam

Возможность связать предложение or вместе с предложением where в запросе ActiveRecord будет доступно в Rails 5. Смотрите соответствующее обсуждение и запрос на выборку .

Итак, вы сможете делать следующие вещи в Rails 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)
192
K M Rakibul Islam

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

Спасибо Eric-Guo за драгоценный камень где-или , теперь мы можем добавить эту функцию OR в >= Rails 4.2.3, также используя этот драгоценный камень.

12
Dipak Gupta

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

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

Итак, я сделал небольшой взлом:

В моей модели я создал метод private с именем sql_where:

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

Следующим в моей области я создал массив для хранения OR

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-условия: sql_where(name: 'John', role: 'admin') сгенерирует (name = 'John' AND role = 'admin').

4
mtrolle

(Просто дополнение к ответу К. М. Ракибул Ислам.)

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

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

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

Rails 5 имеет возможность для предложения or с where. Например.

User.where(name: "abc").or(User.where(name: "abcd"))
0
Foram Thakral