#はじめに
Railsで別モデルや、アソシエーションが遠いモデルのデータ情報を元にフィルタリングしたい時があり、書き方が分からなかったのでメモさせていただきます。
##モデルとアソシエーション
状況のイメージは下記図になります。
下記図でいうと、Topicテーブルのカラムである**week_id
**でArticleテーブルのデータをフィルタリングしたい・・・
モデルとアソシエーションは以下になります。
class Article < ApplicationRecord
has_many :article_items, dependent: :destroy
end
class ArticleItem < ApplicationRecord
belongs_to :article
belongs_to :topic_item
end
class TopicItem < ApplicationRecord
has_one :article_item
belongs_to :topic
end
class Topic < ApplicationRecord
has_many :topic_items, dependent: :destroy
end
『ArticleモデルとTopicモデルにアソシエーションを持たせれば?』と考えましたが、あまりデータ構造はいじらないでくれ、と言われたことがあったので、アソシエーションはいじらない前提です。
結論
class ArticlesController < ApplicationController
def index
@articles = Article.filter_week(params[:week_id_in])
end
end
def filter_week(week_id_in)
joins(article_items: {topic_item: :topic}).where(topics: {week_id: week_id_in})
end
多くの場合indexコントローラーで表示するデータは別モデルのパラメーターがある場合にみ表示されることはないかと思いますが、今回は説明用ということでフィルターの該当部分のみ記載しております。
ここでは**articles_controller
でfilter_week
というメソッドを定義し、引数にパラメーターのweek_id_in
を渡します。
パラメーターのweek_id_in
**は以下のような想定です。
Parameters: {"week_id_in"=>["1", "3", "5"]}
**filter_week
メソッドはarticle.rb
に記載し、joins
を用いて目的のテーブル(ここではtopicsテーブル)まで結合し、whereでパラメーターのweek_id_in
を用いてweek_id
**をフィルターすることができました。
最後に
『実現したい処理』はハッキリしてても今回のような**『書き方が分からないだけで闇雲に時間を費してしまう』**ことは減らしていきたいです。
同じ状況の方がいれば本記事がお役に立てれば幸いです!