バージョンの問題で5.1.以下の複数の小モデルを使ったor検索の実装方法があまり載っていなく少しでも役に立つかもと思ったので投稿します。
もっと良い書き方があれば教えていただきたいです。
学んだこと
・includeを使うと小モデルのオブジェクトを親クラス内から使えるということを学びました。
Child.include(:parent).is_summer_vacation
・idを使ってor検索を実装すること(rails5.2からは.or()を使っていけるかも)
環境
Rails 5.1.6.2
Ruby 2.5.0
DB
book.rb
has_one: business #ビジネス書
has_one: novel #小説
has_one: comic #漫画
複数の小モデルを跨いだor検索
本の検索サービスにおいてアメトークで紹介された本を絞り出すという状況を想定して実装コードを紹介します。
Book.rb
def book_search(status)
if status == "ametolk"
# statusがametolkのparamsがリクエストされた時
business_book_ids = Business.includes(:book).where(is_introduced_ametalk: true).
pluck(:book_id).uniq
novel_book_ids = Novel.includes(:book).where(is_introduced_ametalk: true).
pluck(:book_id).uniq
Book.where(id: business_book_id + novel_book_ids)
elsif
.
.
end
end
scopeを使ってあげるとちょっとスッキリ書けます。
user.rb
scope: business_ametalk, -> { Business.includes(:book).where(is_introduced_ametalk: true)}
scope: novel_ametalk, -> { Novel.includes(:book).where(is_introduced_ametalk: true)}
def book_search(status)
# statusがametolkのparamsがリクエストされた時にor検索をする
if status == "ametolk"
business_book_ids = Book.business_ametalk.pluck(:book_id).uniq
novel_book_ids = Book.novel_ametalk.pluck(:book_id).uniq
Book.where(id: business_book_ids + novel_book_ids)
elsif
.
.
end
end
参考記事