2016-06-24 71 views
0

我正在構建一個Rails應用程序來學習軌道上的紅寶石(我很沒經驗) 我試圖實現一個搜索欄到應用程序。Rails搜索表單返回錯誤找不到產品'id'=搜索

當我打的搜索軌回拋出這個錯誤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 

這is 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中我已經從before_action :set_product

回答

1

的路線讀從上到下

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

對不起,it' s仍然給這個錯誤,但猜測很好....我真的認爲這可能是正確的解決方案 – DaudiHell

+0

請參閱我的編輯請 –

+0

謝謝,但根據j-dexx答案更早地更改過濾器,看起來似乎不是問題 – DaudiHell

1

刪除搜索。

/products/search之前宣佈resources :products導致匹配。

移動此行

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

感謝,但它仍然給了我這個錯誤,如果我刪除它 – DaudiHell

1

代碼的控制器能夠解釋的PARAMS和..

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],則 「搜索」,而params [:查詢]是「臺」,這似乎是好的,你在控制器中做了什麼是

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

這段代碼似乎並沒有執行時,喲ü單擊搜索底部它是使用get方法執行搜索動作,但它又移動到顯示動作,並且在show動作之前設置了實例變量,並且'search'的params [:id]查詢爲@product = Product.find( '搜索')。錯誤是顯而易見的。

你有沒有弄清楚你的路徑設定爲後

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

和您發送GET請求..

+0

謝謝@Shadow,是的,這是有問題的問題,有時問題是如此明顯,以至於看不到它:) – DaudiHell

+1

歡迎@DaðiHall:)。我們在這裏互相幫助 –