Как использовать условие OR в запросе ActiveRecord

Я хочу захватить всех пользователей, у которых либо есть электронное письмо, либо как первое, так и последнее имя. Так, например:

users = User.where(:first_name => "James", :last_name => "Scott")

который вернет всех пользователей, у которых есть первое и последнее имя "Джеймс" и "Скотт".

users = User.where(:email => "[email protected]")

который вернет пользователя с адресом электронной почты как "[email protected]".

Есть ли способ сделать предложение where, чтобы вернуть либо пользователей с тем же именем и фамилией, и пользователь с адресом электронной почты, который соответствует одному запросу where, или мне нужно выполнить слияние на 2 отдельных предложения where.

Ответ 1

Rails 5 поставляется с or методом.

Этот метод принимает объект ActiveRecord::Relation. например:

User.where(first_name: 'James', last_name: 'Scott')
    .or(User.where(email: '[email protected]'))

Ответ 2

Попробуйте следующее:

users = User.where("(first_name = 'James' and last_name = 'Scott') or email = '[email protected]'")

Чтобы интерполировать переменные:

users = User.where("(first_name = ? and last_name = ?) or email = ?", first_name, last_name, email)

Ответ 3

Если вы предпочитаете подход DSL (без SQL), можете использовать базовый слой Arel:

t = User.arel_table
users = User.where(
  (t[:first_name].eq('Ernie').and(t[:last_name].eq('Scott')).
    or(t[:email].eq('james#gmail.com'))
)

Это немного уродливо, но если вы используете некоторую оболочку над Arel (например, этот), код намного приятнее:

users = User.where(
  ((User[:first_name] == 'Ernie') & (User[:last_name] == 'Scott')) |
   (User[:email] == 'james#gmail.com')
)

Ответ 4

Если вы не хотите писать SQL, как упомянули другие, вы можете получить доступ к структурам isl напрямую (это похоже на другой ответ) или использовать squeel, чтобы сделать это гораздо элегантнее:

User.where{(first_name == 'Ernie') & (last_name == 'Scott') | (email == 'james#gmail.com')}