なんで文字列を渡したくないのか
- なんとなく文字列で渡すというのが地に足がついてない感じでイヤ
- DBの種類を変えると動かなくなる可能性がある
-
merge
ができないことがある
例えばこんなの書きたくない
比較演算
target_age = 30
User.where('age >= ?', target_age)
or
target_name1 = '山田'
target_name2 = '田中'
User.where('name=? OR name=?', target_name1, target_name2)
like
target_letter = '田'
User.where('name like ?', "%#{target_letter}%")
Arel::tableを使う
ActiveRecordは内部でArelというSQL生成用ライブラリを使用している。
直接使うこともできるので、Arelで作ったSQLを文字列の代わりにwhereに渡してやろう、ということ。
比較演算
target_age = 30
User.where(User.arel_table[:age].gt(target_age))
ちなみに、
- = (equal) :
eq
- < (less than) :
lt
- <= (less than equal) :
lteq
-
(greater than) :
gt
-
= (greater than equal) :
gteq
or
target_name1 = '山田'
target_name2 = '田中'
User.where(User.arel_table[:name].eq(target_name1).or(User.arel_table[:name].eq(target_name2)))
like
target_letter = '田'
User.where(User.arel_table[:name].matches("%#{target_letter}%"))
Squeelを使えばもっといい感じに!
Arel::table
でもとりあえず当初の目的は達成できたけど、如何せん長い…
Gemを入れてよければ、Squeel
を使えばスッキリ書ける。
比較演算
target_age = 30
User.where{age >= target_age}
()
ではなく{}
を使う。
or
target_name1 = '山田'
target_name2 = '田中'
User.where{(name == target_name1) | (name == target_name2)}
||
ではなく|
。
ちなみにandも&&
ではなく&
。
like
target_letter = '田'
User.where{name =~ "%#{target_letter}%"}
これだけ見るとSqueel
の完全勝利に見えるけど、
Arel::table
だとSQLの生成式を関数化して、複数箇所で使いまわせたりして便利だったりするのかな。
参考
ActiveRecord4でこんなSQLクエリどう書くの? Arel編
ActiveRecord4でこんなSQLクエリどう書くの? Squeel編