ActiveRecord Arel OR condition
I'm a little late to the party, but here's the best suggestion I could come up with:
admins = User.where(:kind => :admin)
authors = User.where(:kind => :author)
admins = admins.where_values.reduce(:and)
authors = authors.where_values.reduce(:and)
User.where(admins.or(authors)).to_sql
# => "SELECT \"users\".* FROM \"users\" WHERE ((\"users\".\"kind\" = 'admin' OR \"users\".\"kind\" = 'author'))"
Complex Arel conditions with AND and OR
You can use table.grouping
method to wrap the expression in a parenthesis, so the whole thing can be like this
table = Assignment.arel_table
where(
table[:from].gt(date.at_end_of_week).
or(
table.grouping(table[:to].not_eq(nil).and(table[:to].lt(date.at_end_of_week)))
).not
)
Grouping AND and OR clauses with Arel
Unless I'm reading wrong, this might be easier using something like active_record_or rather than using arel directly.
Using that gem, you should be able to get the right result doing something like:
common_assert = where(a: true) # WHERE a
option_one = where(b: true).where(c: true) # b AND c
option_two = where(d: true).where(e: true) # d AND e
option_three = where(f: true).where(g: true) # f AND g
combined_optionals = option_one.or.option_two.or.option_three # (b AND c) OR (d AND e) OR (f AND g)
common_assert.merge(combined_optionals) # WHERE a AND ((b AND c) OR (d AND e) OR (f AND g))
Rails Arel joins with where condition on joined table
This should do it.
# Generate Arel tables for both
posts = Arel::Table.new(:posts)
users = Arel::Table.new(:users)
# Make a join and add a where clause
posts.join(:users).on(posts[:user_id].eq(users[:id])).where(users[:first_name].eq('Mark'))
Arel: Dynamically generate conditions from array of values
Whoops - it's super easy with Arel.
Table.where(Table.arel_table[:text].matches_any(patterns))
I'd still like to know more about chaining Arel conditions.
Re-write ActiveRecord query in Arel
This should work:
offers = Offer.arel_table
offers_with_nil_ended_at = offers[:ended_at].eq(nil)
offers_within_range = offers[:started_at].lt(Time.zone.now).and(
offers[:ended_at].gteq(Time.zone.now)
)
Offer.where(offers_with_nil_ended_at.or(offers_within_range))
Related Topics
How to Change MySQL Table Names in Linux Server to Be Case Insensitive
MySQL Select 10 Random Rows from 600K Rows Fast
Sort by Column Asc, But Null Values First
Need to Return Two Sets of Data With Two Different Where Clauses
What Is the Major Difference Between Varchar2 and Char
Does Postgresql Support "Accent Insensitive" Collations
Listagg Function: "Result of String Concatenation Is Too Long"
Sqlite Reset Primary Key Field
Difference Between Having and Where in Sql
Commit Data in a MySQL Container
Insert into ... Values ( Select ... from ... )
Solutions For Insert or Update on SQL Server
Recommended SQL Database Design For Tags or Tagging
When Should I Use Cross Apply Over Inner Join
How to Delete from Multiple Tables in MySQL