yield_self를 사용하여 특정 조건에서만 where 절을 사용하도록 설정한 이야기
8190 단어 where 절루비RailsActiveRecord
처음에는 단순히 if문으로 분기하고 있었습니다만, 너무 어색하다고 생각했기 때문에 분투해 보았습니다.
샘플 코드
if kind == 'hoge'
User.where(kind: kind)
else
User.all
end
ActiveRecord 확장
이 기사을 참고로 ActiveRecord를 확장해 보았습니다.
기사의 확장 코드는 Rails5에서 작동하지 않았기 때문에 Rails의 코드를 읽으면서 다음과 같이 확장했습니다.
확장 코드
ActiveRecord::QueryMethods::WhereChain.include(Module.new do
def if(condition, opts, *rest)
return @scope unless condition
@scope.where_clause += @scope.send(:where_clause_factory).build(opts, rest)
@scope
end
end)
샘플 코드
kind = 'hoge'
User.where.if(kind == 'hoge', kind: kind).to_sql
=> "SELECT `users`.* FROM `users` WHERE `users`.`kind` = hoge"
kind = 'fuga'
User.where.if(kind == 'hoge', kind: kind).to_sql
=> "SELECT `users`.* FROM `users`"
좋은 느낌입니다
리뷰에서 거부됨
도야 얼굴로 풀릭을 보내는 것도 리뷰에서 아래의 지적을 받았습니다.
가장. . . 라고 밖에 말할 수 없었기 때문에 확장 코드의 채용은 배웅했습니다.
yield_self 사용
이제 if문으로 쓸까라고 포기하고 있었는데, yield_self를 사용해서는 어떨까라고 조언을 받았습니다.
yield_self를 사용한 코드가 여기.
샘플 코드
kind = 'hoge'
User.yield_self{|scope| kind == 'hoge' ? scope.where(kind: kind) : scope.all }.to_sql
=> "SELECT `users`.* FROM `users` WHERE `users`.`kind` = hoge"
kind = 'fuga'
User.yield_self{|scope| kind == 'hoge' ? scope.where(kind: kind) : scope.all }.to_sql
=> "SELECT `users`.* FROM `users`"
다음과 같이 QueryMethod를 연결할 수도 있습니다.
샘플 코드
kind = 'hoge'
User.yield_self{|scope| kind == 'hoge' ? scope.where(kind: kind) : scope }.where(age: 0..10).to_sql
=> "SELECT `users`.* FROM `users` WHERE `users`.`kind` = hoge AND (`users`.`age` BETWEEN 0 AND 10)"
kind = 'fuga'
User.yield_self{|scope| kind == 'hoge' ? scope.where(kind: kind) : scope }.where(age: 0..10).to_sql
=> "SELECT `users`.* FROM `users` WHERE (`users`.`age` BETWEEN 0 AND 10)"
yield_self를 사용한 코드는 무사히 LGTM 받았습니다
요약
Reference
이 문제에 관하여(yield_self를 사용하여 특정 조건에서만 where 절을 사용하도록 설정한 이야기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/kasima/items/c7d13855f1a0300f14cb텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)