【问题标题】:Rails search form throwing back error Couldn't find Product with 'id'=searchRails 搜索表单抛出错误找不到带有“id”=search 的产品
【发布时间】:2016-06-24 14:56:47
【问题描述】:

我正在构建一个 Rails 应用程序来学习 Rails 上的 Ruby。(我非常缺乏经验) 我正在尝试在应用中实现搜索栏。

当我点击搜索栏时,会返回此错误 Couldn't find Product with 'id'=search

在这一行 # Use callbacks to share common setup or constraints between actions. def set_product @product = Product.find(params[:id]) end

服务器日志显示了这个

Started GET "/products/search?utf8=%E2%9C%93&query=Desk" for ::1 at 2016-06-24 16:02:32 +0000
Processing by ProductsController#show as HTML
 Parameters: {"utf8"=>"✓", "query"=>"Desk", "id"=>"search"}
 Product Load (0.4ms)  SELECT  "products".* FROM "products" WHERE "products"."id" = $1 LIMIT 1  [["id", 0]]
Completed 404 Not Found in 4ms (ActiveRecord: 0.4ms)

ActiveRecord::RecordNotFound (Couldn't find Product with 'id'=search):
app/controllers/products_controller.rb:77:in `set_product'

我已经在这个搜索表单上工作了几个小时,并查看了各种教程和 stackoverflow 帖子,试图弄清楚这一点。 我完全迷路了,但解决方案可能很简单。 谁能帮帮我。

这是我在 _navbar.html.erb 中的搜索表单

    <div class="input-group">

    <%= form_tag search_products_path, method: 'get', class: 'navbar-form' do %>
      <%= text_field_tag :query, params[:query], placeholder: "Search", class: "form-control"%>
    </div>
     <span class="input-group-btn">
       <%= submit_tag "Search", class: 'btn btn-default' %>
    </span>

  <% end %>

这是 products.rb 模型

class Product < ActiveRecord::Base


  mount_uploader :image, ImageUploader

  validates_presence_of :name, :price, :stock_quantity
  validates_numericality_of :price, :stock_quantity

  belongs_to :designer
  belongs_to :category
  belongs_to :page

  def self.search(query)

    where("name LIKE ? OR description LIKE ?", "%#{query}%", "%#{query}%") 
  end

 end

这是 products_controller.rb

 class ProductsController < ApplicationController
  before_action :set_product, only: [:show, :edit, :update, :destroy]
  before_filter :initialize_cart
  before_action :authenticate_admin!, only: [ :new, :edit, :update, :create, :destroy ]
  # GET /products
  # GET /products.json
  def index
   @products = Product.all
  end

  def search

    @products = Product.search(params[:query]).order("created_at DESC")
    @categories = Category.joins(:products).where(:products => {:id => @products.map{|x| x.id }}).distinct

  end

  # GET /products/1
  # GET /products/1.json
  def show

  end

  # GET /products/new
  def new
   @product = Product.new
  end

  # GET /products/1/edit
  def edit

  end

  # POST /products
  # POST /products.json
  def create
    @product = Product.new(product_params)

    respond_to do |format|
  if @product.save
    format.html { redirect_to @product, notice: 'Product was successfully created.' }
    format.json { render :show, status: :created, location: @product }
  else
    format.html { render :new }
    format.json { render json: @product.errors, status: :unprocessable_entity }
     end
   end
  end

  # PATCH/PUT /products/1
  # PATCH/PUT /products/1.json
  def update
     respond_to do |format|
       if @product.update(product_params)
         format.html { redirect_to @product, notice: 'Product was successfully updated.' }
         format.json { render :show, status: :ok, location: @product }
       else
         format.html { render :edit }
         format.json { render json: @product.errors, status: :unprocessable_entity }
       end
     end
   end

   # DELETE /products/1
   # DELETE /products/1.json
   def destroy
     @product.destroy
     respond_to do |format|
     format.html { redirect_to products_url, notice: 'Product was successfully destroyed.' }
     format.json { head :no_content }
   end
 end

 private
    # Use callbacks to share common setup or constraints between actions.
    def set_product
     @product = Product.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
   def product_params
     params.require(:product).permit(:name, :description, :price, :image, :category_id, :stock_quantity, :designer_id, :query)
   end
 end

这是views/products/search.html.erb

 <table class="table table-hover">
   <thead>
     <tr>
       <th>Name</th>
       <th>Description</th>
       <th>Designer</th>
       <th>Price</th>
       <th>Stock</th>
       <th>Image</th>

    </tr>
   </thead>

 <tbody>
   <% @products.each do |product| %>

     <tr>
        <td><%= link_to product.name, product %></td>
        <td><%= product.description %></td>
        <td><%= product.designer.designer_name %></td>

        <td><%= number_to_currency product.price %></td>
        <td><%= product.stock_quantity %></td>

        <td><%= image_tag product.image.thumb %></td>


    <% end %>
   </tr>
 </tbody>

在 routes.rb 我有

 Rails.application.routes.draw do
  post 'products/search' => 'products#search', as: 'search_products'
  get 'pages/index'

  get 'pages/about'

  get 'pages/location'

  get 'pages/stockists'

  devise_for :users
   resources :categories
   resources :categories
   resources :designers
   resources :category_names
   resources :products


   resource :cart, only: [:show] do
    post "add", path: "add/:id", on: :member
   get :checkout
  end

  resources :orders, only: [ :index, :show, :create, :update ] do
    member do
     get :new_payment
      post :pay
    end
  end


   root 'pages#index'

end

【问题讨论】:

    标签: ruby-on-rails ruby search


    【解决方案1】:

    从上到下读取路线。

    /products/search 之前声明resources :products 会导致匹配。

    移动这条线

    post 'products/search' => 'products#search', as: 'search_products'
    

    在这行之前

       resources :products
    

    否则您的应用会尝试使用 id:'search'... 更新您的产品...这当然不存在

    更新

    此外,您必须从过滤器中删除 :search

    控制器中的这一行

    before_action :set_product, only: [:show, :edit, :update, :destroy, :search]
    

    应该变成

    before_action :set_product, only: [:show, :edit, :update, :destroy]
    

    因为关联产品的路由中没有:id

    新更新 您正在使用 get 表单,但您声明了 post 路由。

    更改路线

    get 'products/search' => 'products#search', as: 'search_products'
    

    【讨论】:

    • 对不起,它仍然给出这个错误,不过猜得不错....我真的认为这可能是正确的解决方案
    • 谢谢,但根据 j-dexx 的答案,请提前更改过滤器,这似乎不是问题
    • 是的,完全一样 ActiveRecord::RecordNotFound in ProductsController#show Couldn't find Product with 'id'=search ` # 使用回调在动作之间共享通用设置或约束。 def set_product @product = Product.find(params[:id]) end`
    • 哈哈哈.....太简单了,我花了一整天的时间才弄明白,非常感谢,你是传奇和英雄:)
    • 嘿,@Ruby Racer,如果你今天很火,你可能想看看我的这个问题;)stackoverflow.com/questions/37934228/…
    【解决方案2】:

    before_action :set_product中删除搜索

    【讨论】:

    • 谢谢,但如果我删除它仍然会给我这个错误
    【解决方案3】:

    控制器中的参数和代码可以解释..

    Processing by ProductsController#show as HTML
     Parameters: {"utf8"=>"✓", "query"=>"Desk", "id"=>"search"}
     Product Load (0.4ms)  SELECT  "products".* FROM "products" WHERE "products"."id" = $1 LIMIT 1  [["id", 0]]
    Completed 404 Not Found in 4ms (ActiveRecord: 0.4ms)
    
    ActiveRecord::RecordNotFound (Couldn't find Product with 'id'=search):
    app/controllers/products_controller.rb:77:in `set_product'
    

    在参数中,params[:id] 是“search”,params[:query] 是“Desk”,这看起来没问题,而您在控制器中所做的是

    @products = Product.search(params[:query]).order("created_at DESC")
    @categories = Category.joins(:products).where(:products => {:id => @products.map{|x| x.id }}).distinct
    

    当您单击搜索底部时,此代码似乎没有执行,它正在使用 get 方法进行搜索操作,但它再次移动以显示操作,并且您在显示操作之前设置了实例变量,并且您的 params[:id] 是' search' 查询为@product = Product.find('search')。错误很明显。

    你确定你的路线设置为帖子

     post 'products/search' => 'products#search', as: 'search_products'
    

    你正在发送获取请求..

    【讨论】:

    • 感谢@Shadow,是的,这似乎是问题所在,有时问题非常明显,以至于看不到它:)
    • 欢迎@DaðiHall :)。我们在这里互相帮助
    猜你喜欢
    • 1970-01-01
    • 2019-05-11
    • 1970-01-01
    • 2013-06-03
    • 2021-01-24
    • 1970-01-01
    • 1970-01-01
    • 2016-01-06
    相关资源
    最近更新 更多