@ebbb6fdc72nx5x1
Revisions
Report this question
Subscribe question
Help us understand the problem. What is going on with this question?
Q&A
Closed

Ruby on Railsでransackを用いた検索機能の実装時のエラー

解決したいこと

現在写真管理アプリみたいなのを作成中で検索機能をつけたく、ransackを用いて実装していました。
しかし検索ボタンを押すとエラーが起きてしましい、解消法がわからず質問に至ったしだいです。
なぜかshowメソッドが動くのはどうしてでしょうか?
アイテムテーブルの中にcategoryカラムを入れておりカテゴリーテーブルとアソシエーションを組んであります。

発生している問題・エラー

ActiveRecord::RecordNotFound in ItemsController#show
Couldn't find Item with 'id'=search

Extracted source (around line #69):           

  def set_item 
    @item = Item.find(params[:id]) 
  end

該当するソースコード items_controller.rb

class ItemsController < ApplicationController
  before_action :authenticate_user!, except: :index
  before_action :set_item, only: [:show, :edit, :update, :destroy]
  before_action :set_user, only: [:show, :edit, :update, :destroy]
  before_action :search_item, only: [:index, :search]

  def index
    if user_signed_in?
      @item = Item.all.where(user_id: current_user.id)
      @item = @item.order('created_at DESC')
      set_category_column
    end
  end

  def new
    @item = Item.new
  end

  def create
    @item = Item.new(item_params)
    if @item.save
      redirect_to root_path
    else
      render 'new'
    end
  end

  def show
  end

  def edit
  end

  def update
    if @item.update(item_params)
      redirect_to item_path(@item.id)
    else
      render 'edit'
    end
  end

  def destroy
    if @item.destroy
      redirect_to root_path
    else
      render 'show'
    end
  end

  def search
    @results = @search.result.uncludes(:category)  # 検索条件にマッチした商品の情報を取得
    binding.pry
  end




  private

  def search_item
    @search = Item.ransack(params[:q])  # 検索オブジェクトを生成
  end

  def item_params
    params.require(:item).permit(:explanation, :category_id, :season_id, :brand, :purchase_day, :price, :place, :image).merge(user_id: current_user.id)
  end

  def set_item 
    @item = Item.find(params[:id]) 
  end

  def set_user
    unless user_signed_in? && current_user.id == @item.user_id
      redirect_to root_path
    end
  end

  def set_category_column
    @category_name = Category.select("name").distinct
  end
end

index.html.reb

<%= search_form_for @search, url: items_search_path do |f| %>
                <%= f.label :category_name_eq, 'カテゴリー:' %>
                <%= f.collection_select :category_name_eq, @category_name, :name, :name %>
                <br>
            <%= f.submit '検索' %>
            <% end %> 

自分で試したこと

サーチメソッドにbinding.pryを記述したが止まらないため、メソッドがうまく動いてないのは確認できたのですが
なぜshowメソッドが動くのか分かりません。
未熟者で質問の至らぬ点が多々あるかと思いますが、よろしくお願いします。

1
2
Answer

routes.rbは上からマッチすると思うので、
/items/search/items/:idにマッチしてしまった、的な話かもしれません。
質問文に、routes.rbと、bin/rake routesの内容を記載すると助けになるかもしれませんね。

あと、ransackのコードを読むと、search_form_forのオプションは概ねform_forに委譲されていますが、
methodオプションは、HTTPメソッドの指定に使うものであり、
今回のように、Railsのaction名を指定するのはちょっと違うような気がします。

(GETじゃなくなったのでPOST扱いになり、showにはならなくなった? 正確な挙動は不明)

1
ご回答ありがとうございます。

Rails.application.routes.draw do
root to: "items#index"
get 'search', to: 'items#search'
devise_for :users
resources :items
end

routes.rbをこのように記載したら、できました!
routes.rbは上からマッチするってことは知りませんでしたので、勉強になりました。また、それが原因でエラーが起こっていた事が知れてモヤモヤが解消されました。
ありがとうございました。
解決して良かったです~
View the remaining 1 comments.

なんとか自力で解決
どうしてもshowメソッドが動いてしまうので、
<%= search_form_for (@search, url: items_search_path, method: :search) do |f| %>
でメソッドを指定しました。
そしたら今度はRouting Errorが出たのでそこは簡単に解決。
なんか無理やりやった感じになってしまいましたが、一応解決です。
ただこの解決の仕方じゃない解決方法を知っている方がいらっしゃったらまだ回答を募集しておりますので、よろしくお願いします。

0
Help us understand the problem. What is going on with this answer?
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login