Rails 中没有路线匹配重复错误。如何调试?

Posted

技术标签:

【中文标题】Rails 中没有路线匹配重复错误。如何调试?【英文标题】:No route matches in Rails for duplicate error. How to debug? 【发布时间】:2012-12-02 19:20:15 【问题描述】:

所以我得到了这个错误:

Routing Error

No route matches :action=>"show", :controller=>"products", :list_id=>#<Product id: 1, name: "a", model: "", description: "", version: "", company: "", price: nil, image_source: nil, created_at: "2012-12-02 18:43:26", updated_at: "2012-12-02 18:43:26">

Notice :list_id=>#... 看起来有点搞砸了。不知何故 Product 进来了。

这是product.rb

class Product < ActiveRecord::Base
  attr_accessible :company, :description, :model, :name, :price, :version

  has_many :list_product_interactions
  has_many :lists, :through => :list_product_interactions

  validates_uniqueness_of :name, :scope => [:version]

这里是list.rb

class List < ActiveRecord::Base
  attr_accessible :activity, :description, :title

  has_many :list_product_interactions
  has_many :products, :through => :list_product_interactions, :order => "list_product_interactions.votes_up DESC"

这里是 list_product_interactions.rb

class ListProductInteraction < ActiveRecord::Base
  attr_accessible :list_id, :product_id, :votes_activity, :votes_down, :votes_total, :votes_up

  belongs_to :list
  belongs_to :product

当我创建产品的副本(名称已被占用的产品)时,会发生错误。这是发生错误的控制器:

products_controller.rb

class ProductsController < ApplicationController
  def create
    @list = List.find(params[:list_id])
    @product = @list.products.build(params[:product])
    if @list.save
      raise "ok"
      redirect_to list_path(@list)
    else
      @list.reload
      params[:list_id] = @list.id
      render template: "lists/show"
    end
  end

  def show
    @product = Product.find(params[:id])
  end
end

如何调试?谢谢

更新:添加了 lists_controller.rb

class ListsController < ApplicationController
  def index
    @lists = List.all
  end

  def new
    @list = List.new
  end

  def create
    @list = List.new(params[:list])
    if @list.save
      redirect_to @list
    else
      render :new
    end
  end

  def show
    @list = List.find(params[:id])
    @product = @list.products.build
    nil
  end
end

列表显示模板

h1
  = @list.title
br
= @list.description
hr
- @list.products.each do |product|
  - if !product.id.nil?
    = link_to product.name, list_product_path(product), class: "product_link"
    '
    = product.version
    '
    = link_to "up:", "/lists/#@list.id/products/#product.id/vote_up", :method => :put
    = product.product_up_votes(@list.id)
    '
    = link_to "down:", "/lists/#@list.id/products/#product.id/vote_down", :method => :put
    = product.product_down_votes(@list.id)

hr
h3 Add products:
= form_for([@list, @product]) do |f|
  - if @product.errors.any?
    |product errors
    = pluralize(@product.errors.count, "error")
    ul
    - @product.errors.full_messages.each do |msg|
      li
        = msg
  br
  = f.label :name
  = f.text_field :name
  br
  = f.label :version
  = f.text_field :version
  br
  = f.submit
hr
= link_to "All lists", lists_path

【问题讨论】:

能否提供"lists/show"模板 添加了列表控制器和显示模板。 【参考方案1】:

使用 ruby​​-debug 调试 Rails


Rails 使用的调试器 ruby​​-debug 是一个 gem。要安装它,只需运行:

sudo gem install ruby-debug
# if you run 1.9
sudo gem install debugger

然后你可以做类似的事情

<% debugger;true %>
# or in the controller/model/lib
def somemethode
    # ... 
    debugger
    # ...
end

当解释器到达debugger 语句时,它会停止并让您在控制台中交互式地探索当前环境。

您的问题


...可能位于此处:

    = link_to product.name, list_product_path(product), class: "product_link"

那是因为 list_product_path 很可能需要一个列表对象和相应的产品,例如 list_product_path(@list,product) 或者您的意思可能是 lists_products_path(product)

【讨论】:

【参考方案2】:

您的 :list_id 参数的值有问题:

Routing Error
No route matches :action=>"show", :controller=>"products", 
  :list_id=>#<Product id: 1, name: "a", model: "", description: "", version: "", company: "", price: nil, image_source: nil, created_at: "2012-12-02 18:43:26", updated_at: "2012-12-02 18:43:26">

由于这是一个路由错误,您可能应该发布您的 /config/routes.rb 以及 rake routes 的输出。

据我所知,您似乎依赖于嵌套资源路由,如下所示:

#/config/routes.rb
resources :lists do
  resources :products
end

如果那是真的,那么 krichard 可能是正确的,所以你应该使用

list_product_path(:id => product.id, :list_id => @list.id )
list_product_path(product,@list)     #this should also work

如果不同时传递product.idlist.id,您的请求将与您的嵌套资源路由不匹配

【讨论】:

以上是关于Rails 中没有路线匹配重复错误。如何调试?的主要内容,如果未能解决你的问题,请参考以下文章

带有设计的 Rails 3:没有路线匹配 /d/users/sign_out

没有路线匹配 [GET] "/users/sign_out" rails 5

rails 6中没有针对多个路线参数的路线匹配

路由错误克隆目录后没有路由匹配 [GET] "/logout"

没有路线匹配 [GET] /assets

如何以及在哪里提交 Rails 上的表单值?