先日書いた記事の付け足しになりますね。orを利用して検索ロジックを書いていましたが
mergeや、whereを利用することで構造に不一致になるケースがあり、HACK,WORKAROUNDで対処しました。
原因はなんとなくイメージできているんですが、詳しい方いましたら、教えて頂きたいです。
- 完全に再現できるソースではなく、イメージです。
models
まず、モデルはこの親子関係になります。
# app/models/user.rb class user < ApplicationRecord has_many :shops end # app/models/shop.rb class shop < ApplicationRecord belongs_to :user end
controller
app/controllers/users.rb
class Users < ApplicationController
def search
relations = user.joins(:shop).where(name: 'hoge')
relations = if params[:conditions] == 'or'
relations.or(relations.where(age: 19)
else
# relations.joins_valuesが更新される
relations.merge(relations.where(age: 19))
end
render json: relations.to_json({ include: :shops })
end
end
relations.joins_values
これで、引数とレシーバーの構造が一致しているか検証しています。
joinsの引数(上記のサンプルコードでは、:shop)が入っていますので、これが一致するか見ています。
捕捉ですが、limit, offset, distinctも見ています。
WORKAROUND
修正したのは下記。
app/controllers/users.rb
class Users < ApplicationController
def search
relations = user.joins(:shop).where(name: 'hoge')
relations = if params[:conditions] == 'or'
relations.joins_values = relatoins.joins_values.uniq # HACK:
relations.or(relations.where(age: 19)
else
relations.merge(relations.where(age: 19)
end
render json: relations.to_json({ include: :shops })
end
end
joins_valuesを上書きすることで対応した。これmergeをしているからjoins_valuesの値も追加されているのかと思い、whereに変えてみたが、
joins_valuesの値は変わらず。githubで調べるのはこのぐらいにして一時的な対応です。