Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to control bracket position on ActiveRecord query with `OR` clause

I want to generate the following SQL query using ActiveRecord for Rails:

SELECT * FROM users WHERE (((1 IS NULL) OR (10 > 20)) AND (2 IS NULL OR (10 > 1)));

So I wrote the following scope:

where('1 IS NULL')
  .or(where('10 > 20'))
  .where('2 IS NULL')
  .or(where('10 > 1'))

However I am getting a slightly different query:

SELECT * FROM users WHERE (((1 IS NULL) OR (10 > 20)) AND 2 IS NULL OR (10 > 1));

Note that the first has no brackets surrounding everything after AND whilst the first does. This effects the results I get (the first query evaluates to false whilst the second true).

How can I write the second query using ActiveRecord?

This question seems very similar: How to properly add brackets to SQL queries with 'or' and 'and' clauses by using Arel? Arel is now part of Rails so any answer there should be relevant.

The difference is both queries are the same which lead to a discussion about how to make it clearer, and secondly it was for an older version of Rails so the answers don't seem to work.

I also don't want to need a new gem for this, I think ActiveRecord should be able to handle this.

Edit:

I ended up writing it like this:

where("(1 IS NULL OR 10 > 20) AND (2 IS NULL OR 10 > 1)")

but now I'm just going around ActiveRecord, I was hoping to do it with ActiveRecord

like image 702
KNejad Avatar asked Jun 19 '20 17:06

KNejad


People also ask

Can we use brackets in where clause in SQL?

SQL: Using Parentheses with And / OR condition is necessary with where clause to gives expected result.

What is eager loading rails?

Eager loading lets you preload the associated data (authors) for all the posts from the database, improves the overall performance by reducing the number of queries, and provides you with the data that you want to display in your views, but the only catch here is which one to use. Gotcha!

What is lazy loading in Ruby?

How lazy loading works: Whenever you try to get some data from database, For example, users is the database table that you have. And you are querying database to get users having age less than 20.

What is ActiveRecord relation?

Whereas an instance of ActiveRecord::Relation is a representation of a query that can be run against your database (but wasn't run yet). Once you run that query by calling to_a , each , first etc. on that Relation a single instance or an array of ActiveRecord::Base instances will be returned.


1 Answers

You can get something similar, just without the main parentheses wrapping the where clause conditions:

User.where('foo IS NULL')
    .or(User.where('10 > 20'))
    .merge(User.where(bar: nil).or(User.where('10 > 1')))
# SELECT "users".*
# FROM "users"
# WHERE ((foo IS NULL) OR (10 > 20)) AND ("users"."bar" IS NULL OR (10 > 1))

Consider foo equals 1 and bar equals 2.

like image 81
Sebastian Palma Avatar answered Oct 14 '22 02:10

Sebastian Palma