Rails搜索表单抛出错误无法找到带有'id'=搜索的产品

时间:2016-06-24 14:56:47

标签: ruby-on-rails ruby search

我正在构建一个rails应用程序来学习ruby on rails。(我很缺乏经验) 我正在尝试为应用程序实现搜索栏。

当我点击搜索栏时,会抛出此错误connection.onInitialize( (params) : InitializeResult => { connection.console.log("Initialization : " + params.rootPath); });

在此行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

我已经在这个搜索表单上工作了几个小时,并检查了各种教程和stackoverflow帖子试图解决这个问题。 我完全迷失了,但解决方案可能非常简单。 请任何人帮助我。

这是我在_navbar.html.erb

中的搜索表单
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'

这是products.rb模型

    <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_controller.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

这是views / products / search.html.erb

 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

并且在routes.rb中我有

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

3 个答案:

答案 0 :(得分:1)

before_action :set_product

中删除搜索

答案 1 :(得分:1)

路线从上到下阅读。

resources :products之前宣布/products/search会导致匹配。

移动此行

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

在此行之前

   resources :products

否则,您的应用会尝试使用ID更新您的产品:'搜索'...当然不存在

<强>更新

此外,您必须从过滤器中删除: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'

答案 2 :(得分:1)

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

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方法点击搜索操作但是它再次移动到显示动作并且你在show动作之前设置了实例变量而你的params [:id]是' search'正在查询@product = Product.find('search')。错误很明显。

您是否发现您的路线已设为发布

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

并且您正在发送获取请求..