railsでDBの検索クエリを書くときにscopeを利用することは多い。
scopeで、ある条件の時のみくっつけたいwhere式があるといった場合に、
コードの見通しを損なうことなく書くにはどうしたらよいか、という案をメモっておく
scope :particular_user ,-> (trigger) {
select(:user_id, :user_nm, :age)
.where(user_nm: 'tanaka' )
.merge( trigger ? where(user_id: '00000') : User.all ) # ココ
.where(age: 30)
}
marge()の引数に参考演算子を書き、条件に応じてallに切り替える方法
margeにallを入れると条件として無視される
scope :particular_user ,-> (trigger) {
select(:user_id, :user_nm, :age)
.where( user_nm: trigger ? 'tanaka' : nil ) # ココ
.where(age: 30)
}
where()の場合はnilを入れると条件として無視される
scope :particular_user ,-> (trigger) {
select(:user_id, :user_nm, :age)
.where(user_nm: 'tanaka' )
.admin_user_id(trigger) # ココ
.where(age: 30)
}
# ifをこちらに移す
scope :admin_user_id ,-> (is_admin){
return unless is_admin
where(user_id: '00000')
}
scopeの戻り値がnilであると条件として無視される
where式を追加する条件が満たされない時はnilを返し、条件が満たされる場合はwhereを返すスコープに移す案
scope :particular_user ,-> (trigger) {
obj = select(:user_id, :user_nm, :age).where(user_nm: 'tanaka' ).where(age: 30)
# ココ
# ifブロックとしてなるべく独立させたくない
if trigger
obj.merge( where(user_id: '00000') )
end
}
こういうifブロックを別にすると、増えれば増えるほど見通しが悪くなる気がするのを回避したいという話