🐱

【Ruby on Rails】Ransack4.0.0以上で発生するエラー解消法

2024/07/01に公開

はじめに

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以上特有のエラーとして、下記エラーが出てくるかと思います。
Image from Gyazo

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

Image from Gyazo

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以上特有のエラーとして、下記エラーが出てくるかと思います。
Image from Gyazo

先ほど同様、検索可能な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

Image from Gyazo

こちらも同じく、Ransackを使用するためには、検索可能なUserの関連を明示的に許可する必要があるため、Userモデルにransackable_associationsクラスメソッドを定義します。

  • app/models/user.rbに、下記を追記。エラー文に記載のコードをそのまま持ってきています。
def self.ransackable_associations(auth_object = nil)
    ["articles", "favorites"]
end

このSTEPを踏むとエラー解消し、無事に「記事のタイトル、内容、投稿者名」の曖昧検索ができるようになりました。ありがとうございました。

参考文献

Discussion