2011年2月3日木曜日

[Rails]: Rails3のActiveRecordで複雑なOR文生成

Rails 3のActiveRecordはArelというDSLを使ってクエリを生成するのだが,単純なクエリであればともかく,複雑なクエリを実行しようと思うと色々と四苦八苦しないといけなくなる.
# この辺はどのORMでも同じだけど 今回,複雑なSQL文を作る必要が出たのでその方法をまとめておく.
やりたいことは,以下のような感じ.よくあるたくさんの条件をORで繋いで検索する様なケース.
 
def hoge
  # 条件1の作成
  # 条件2の作成
  some_array.each do |h|
    # 条件3〜nの作成
  end
  # 条件1〜nをORで接続してreturn
end
これをやろうとして,
 
Hoge.where(CONDITION1).or(CONDITION2).or(CONDITION3)
ということが出来れば良かったのだが,これはできない.正しくは,scopedを使って,
 
conds = Array.new
h = Hoge.scoped

conds << h.tables[:field_name].eq('HOGE')
some_array.each do |c|
  conds << h.tables[:field_name].SOME_METHOD()
end
cond = nil
conds.each do |c|
  if not cond
    cond = c
  else
    cond = cond.or(c)
  end
end
return HogeModel.where(cond)
とやるといけた.

生成されるSQL文は「(((COND1 OR COND2) OR COND3) OR COND4)」という形式になるが,論理和演算なので括弧は特に気にしなくても良い. 結局このへんで3時間近くハマってしまった.Rails3系はまだ情報が少ないのが辛いなあ.

0 件のコメント:

コメントを投稿