ответ

153

Способность цепи or положение наряду с where пунктом в ActiveRecord запроса будет доступен в Rails 5. См. related discussion and the pull request.

Таким образом, вы сможете сделать следующие вещи в 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)) 

(|| B) & & C:

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

Как я могу получить (A || B) && (C || D). Я попробовал Post.where (a) .or (Post.where (b)). Где (c) .or (Post.where (d)), но Он производит как: (A || B) && C || D – Imran

+3

@Imran Я считаю, что это будет 'Post.where (a) .or (Post.where (b)). Where (Post.where (c) .or (Post.where (d))), это должно создать (a || b) && (c || d) – engineersmnky

12

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

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

3

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

Но в текущее состояние Rails 5.1.4 «ы это получить слишком сложно, чтобы достичь с Arel или цепью. Но я все еще хотел использовать 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-where: sql_where(name: 'John', role: 'admin') сгенерирует (name = 'John' AND role = 'admin').

Смежные вопросы