1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Railsで別モデルのデータを使って親データのフィルタリングをする方法

Last updated at Posted at 2021-01-14

#はじめに
Railsで別モデルや、アソシエーションが遠いモデルのデータ情報を元にフィルタリングしたい時があり、書き方が分からなかったのでメモさせていただきます。

##モデルとアソシエーション
状況のイメージは下記図になります。
下記図でいうと、Topicテーブルのカラムである**week_id**でArticleテーブルのデータをフィルタリングしたい・・・
スクリーンショット 2021-01-14 22.34.33.png

モデルとアソシエーションは以下になります。

article.rb
class Article < ApplicationRecord
    has_many :article_items, dependent: :destroy
end
article_item.rb
class ArticleItem < ApplicationRecord
    belongs_to :article
    belongs_to :topic_item
end
topic_item.rb
class TopicItem < ApplicationRecord
    has_one :article_item
    belongs_to :topic
end
topic.rb
class Topic < ApplicationRecord
    has_many :topic_items, dependent: :destroy
end

『ArticleモデルとTopicモデルにアソシエーションを持たせれば?』と考えましたが、あまりデータ構造はいじらないでくれ、と言われたことがあったので、アソシエーションはいじらない前提です。

結論

articles_controller.rb
class ArticlesController < ApplicationController
    def index
        @articles = Article.filter_week(params[:week_id_in])
    end
end
article.rb
def filter_week(week_id_in)
    joins(article_items: {topic_item: :topic}).where(topics: {week_id: week_id_in})
end

多くの場合indexコントローラーで表示するデータは別モデルのパラメーターがある場合にみ表示されることはないかと思いますが、今回は説明用ということでフィルターの該当部分のみ記載しております。

ここでは**articles_controllerfilter_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**をフィルターすることができました。

最後に

『実現したい処理』はハッキリしてても今回のような**『書き方が分からないだけで闇雲に時間を費してしまう』**ことは減らしていきたいです。
同じ状況の方がいれば本記事がお役に立てれば幸いです!

1
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?