0
0

Ruby on Rails: Ransackを用いたモデル検索のエラー解決方法①

Last updated at Posted at 2024-05-01

この記事では、Ruby on RailsでRansackを使ってモデルの検索を行う際に発生したエラーの解決方法について説明します。特に、関連するモデルの属性に対する検索のためのホワイトリストの設定や、カスタム検索の実装について触れます。

背景

Railsアプリケーションで、Reservationモデルの検索を行い、予約をした顧客単位で検索する必要がありました。しかし、Ransackの設定や関連するモデルへのアクセスに問題が発生し、検索フォームが正しく動作しないという課題が生じました。

エラー内容

Reservation検索を実装するために、ビューで以下のようにフォームを設定していました:

<%= search_form_for @r, url: reservations_path, method: :get, local: true, class: 'custom-form-group d-flex' do |form| %>
  <div class="form-group d-flex align-items-end me-2">
    <div class="w-100">
      <label>顧客名検索:</label>
      <%= form.search_field :customer_name_cont, id: 'single-simple-search-name_cont', class: 'form-control me-2', placeholder: '顧客名検索' %>
    </div>
  </div>
  <%= form.submit '検索', class: 'btn btn-primary' %>
<% end %>

しかし、これに対して以下のエラーが発生しました:

RuntimeError at /reservations
Ransack needs Customer attributes explicitly allowlisted as searchable.

このエラーは、Ransackが関連するCustomerモデルの属性にアクセスできないために発生しています。

解決方法

  1. Customerモデルでのransackable_attributesメソッドの追加:

    この問題を解決するため、Customerモデルに対するホワイトリストメソッドを追加します:

    class Customer < ApplicationRecord
      # その他のモデル設定...
    
      def self.ransackable_attributes(auth_object = nil)
        %w[city created_at description email id name postal_code prefecture street_address telephone updated_at]
      end
    end
    

    このメソッドで、Customerモデルの検索に必要な属性をホワイトリスト化し、Ransackが正常に検索できるようにします。

  2. Reservationモデルのカスタムransackerの追加:

    次に、Reservationモデルで顧客単位での検索を行うためのカスタムransackerを追加します:

    class Reservation < ApplicationRecord
      # その他の設定...
    
      ransacker :customer_name do |parent|
        # Reservationのcustomer_idを元に、関連するCustomer.nameで検索するための設定
        Arel::Nodes::InfixOperation.new('LIKE', parent.table[:customer_id], '%')
      end
    
      def self.ransackable_attributes(auth_object = nil)
        %w[company_id created_at customer_id date ...]
      end
    end
    
  3. ビューでの検索フォーム:

    最後に、ビュー内で以下のように検索フォームを設定し、customer_name_contなどのフィールドで検索ができるようにします:

    <%= search_form_for @r, url: reservations_path, method: :get, local: true, class: 'custom-form-group d-flex' do |form| %>
      <div class="form-group d-flex align-items-end me-2">
        <div class="w-100">
          <label>顧客名検索:</label>
          <%= form.search_field :customer_name_cont, id: 'single-simple-search-name_cont', class: 'form-control me-2', placeholder: '顧客名検索' %>
        </div>
      <% end %>
    

これらの修正により、RansackでReservationモデルの検索を顧客単位で行うことができるようになります。

次回の記事

0
0
0

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
0
0