【Ruby on Rails】Ransack4.0.0以上で発生するエラー解消法
はじめに
2024/1からプログラミングスクールに通っている初学者です。
2024/6/28より自分自身のアウトプットのために、毎日投稿をしています。(最初の4投稿は、はてなブログを使用していましたが、本日よりZennにシフトいたします。)
初学者の投稿になるため間違い等ございましたら、優しくご指摘いただけますと幸いです。
エラー発生状況
現在RubyonRailsを使用して、投稿機能を有したアプリを作成しております。
その一機能として、gem 'ransack'を使用して検索機能を実装いたしました。
検索項目としては、「記事のタイトル、記事の内容、投稿者名」の曖昧検索となります。
その中で、こちらにも記載がある通り、Ransack4.0.0以上ではモデルに「検索可能な列」や「検索可能な関連モデル」の定義が必要だったので、そのエラー解消法を記載させていただきます。
環境
- Rails 7.1.3.4
- ransack 4.1.1
実装した手順
GitHub, 公式ドキュメントに従って、4.0.0以前と同様にコントローラーとビューファイルにコードを記載しました。
ここからは、下記ステップを踏んで実装しましたので、こちらに沿いながら実装コードを記載していきます。
STEP1: Articleモデルのカラムであるtitleとbodyを検索条件に含める
STEP2: Userモデルのカラムである、nameを検索条件に含める
STEP1: Articleモデルのカラムである、titleとbodyを検索条件に含める
def index
@q = Article.ransack(params[:q])
@articles = @q.result(distinct: true).includes(:user).order(created_at: :desc)
end
- app/views/articles/index.html.erb
- Articleモデルのカラムである、titleとbodyを曖昧検索できるよう、search_field に
title_or_body_cont
を実装。
<%= search_form_for @q do |f| %>
<%= f.search_field :title_or_body_cont %>
<%= f.submit '検索'%>
<% end %>
ここまで実装を進めていくと、Ransack4.0.0以上特有のエラーとして、下記エラーが出てくるかと思います。
Ransack needs Article attributes explicitly allowlisted as
searchable. Define a ransackable_attributes class method in your Article
model,...
Ransackを使うために、検索可能なArticle属性を明示的に許可する必要がある。Articleモデルにransackable_attributesクラスメソッドを定義し、検索可能な属性を指定しましょう、とのことです。
- app/models/article.rbに、下記を追記。エラー文に記載のコードをそのまま持ってきています。
def self.ransackable_attributes(auth_object = nil)
["body", "created_at", "id", "id_value", "title", "updated_at", "user_id"]
end
Ransack needs Article associations explicitly allowlisted as
searchable. Define a ransackable_associations class method in your Article
model,
Ransackを使用するためには、検索可能なArticleの関連を明示的に許可する必要がある。Articleモデルにransackable_associationsクラスメソッドを定義し、検索可能な関連を指定しましょう、とのことです。
STEP1では、Articleモデルのカラムであるtitleとbodyのみ検索条件に含めていますが、UserモデルとArticleモデルは一対多の関係であるため、下記エラーも発生しているようです。
(今回いいね機能を有するfavoriteモデルも入っています)
- app/models/article.rbに、下記を追記。エラー文に記載のコードをそのまま持ってきています。
def self.ransackable_associations(auth_object = nil)
["articles", "favorites"]
end
STEP2: Userモデルのカラムである、nameを検索条件に含める
Articlesコントローラーの記載はそのままで、下記ビューにUserモデルのnameカラムも検索条件に含めるよう指定します。
- app/views/articles/index.html.erb
- Userモデルのnameカラムも検索条件に含めるよう、search_field に
:user_name_or_title_or_body_cont
を実装。
<%= search_form_for @q do |f| %>
<%= f.search_field ::user_name_or_title_or_body_cont %>
<%= f.submit '検索'%>
<% end %>
user_name
としているのは、関連するモデルを跨ぐ際の書き方になります。こちらの記事がわかりやすかったので、詳細はこちらご覧ください。
また実装を進めていくと、Ransack4.0.0以上特有のエラーとして、下記エラーが出てくるかと思います。
先ほど同様、検索可能なUserの関連を明示的に許可する必要があるため、今度はUserモデルにransackable_associationsクラスメソッドを定義します。
- app/models/user.rbに、下記を追記。エラー文に記載のコードをそのまま持ってきています。
def self.ransackable_attributes(auth_object = nil)
["created_at", "crypted_password", "email", "id", "id_value", "name", "salt", "updated_at"]
end
こちらも同じく、Ransackを使用するためには、検索可能なUserの関連を明示的に許可する必要があるため、Userモデルにransackable_associationsクラスメソッドを定義します。
- app/models/user.rbに、下記を追記。エラー文に記載のコードをそのまま持ってきています。
def self.ransackable_associations(auth_object = nil)
["articles", "favorites"]
end
このSTEPを踏むとエラー解消し、無事に「記事のタイトル、内容、投稿者名」の曖昧検索ができるようになりました。ありがとうございました。
Discussion