MetaWhere to Squeel migration
-
22-10-2019 - |
Question
In MetaWhere I combined conditions to sql variable using loops, if else statements.
sql = {}
email_starts_with = "vany%"
sql["growth"] = 0..200
sql = sql & (:rating > 50)
sql = sql & (:email =~ email_starts_with)
.....
.....
User.where(sql).to_sql
=> "SELECT \"users\".* FROM \"users\" WHERE \"users\".\"growth\" BETWEEN 0 AND 200 AND \"users\".\"rating\" > 50 AND \"users\".\"email\" ILIKE 'vany%'"
user = User.where(sql).first
=> #<User id: 1, .................................. >
How can I do the same using Squeel?
Thanks for any help)
Solution 2
I resolved my problem using Arel. I think (I just changed MetaWhere code to Arel) that it is just the same as MetaWhere.
t = User.arel_table
email_starts_with = "vany%"
sql = t[:rating].gt(50)
sql = t[:growth].in(0..200)
sql = sql.and(t[:email].matches(email_starts_with))
User.where(sql).to_sql
=> "SELECT \"users\".* FROM \"users\" WHERE (\"users\".\"growth\" BETWEEN 0 AND 200 AND \"users\".\"email\" ILIKE 'vany%')"
Thanks everybody for help!
OTHER TIPS
check out the "squeel" method, new in 0.9.0. It was added to support exactly this sort of thing. It just gives you an easy way to write a block of Squeel DSL without actually attaching it to a "where", "join", etc.
You also might want to consider encapsulating this logic in a sifter for your model.
class User < ActiveRecord::Base
sifter :my_sifter do |growth_range, min_rating, email_start|
growth.in(growth_range) & rating.gt(min_rating) & email.matches("#{email_start}%")
end
end
User.where{sift :my_sifter, 0..200, 50, 'vany'}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow