【问题标题】:Rails form trouble铁轨形成麻烦
【发布时间】:2011-04-11 17:57:08
【问题描述】:

所以,我有一些奇怪的控制器/视图设置,编辑产品模型对象发生在列表控制器/视图中。对于为什么会这样,有一个冗长的解释,但我离题了。但是,当我提交表单时,我收到错误 Couldn't find Product without an ID 。是什么赋予了?奇怪的是,当我查看随请求发送的参数时,ID 属性被分配给了“格式”键。 ?!。

控制器代码非常简单。编辑操作:

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

更新操作:

def update
  @edit = Product.find(params[:id])

  if @edit.save
    redirect_to :url => listings_display_path
  end
end

这是我的 form_for 代码:

<% form_for @edit, :url => (listings_update_path(@edit)) do |f| %>

编辑,跟踪:

{"utf8"=>"✓",
"_method"=>"put",
"authenticity_token"=>"st17LW0S9uENaV8UBcxKUfRH67oo+r3TuFAxiPKMCEc=",
"product"=>{"brand"=>"test_brand",
"productname"=>"test_product",
"category"=>"test_category",
"regprice"=>"4",
"saleprice"=>"2",
"description"=>"description"},
"commit"=>"Submit",
"format"=>"21"}

编辑:routes.rb

resources :product do
  resources :promotions
  collection do
    get "replace"
  end
end

#listings
match 'listings/index' => 'listings#index'
match 'listings/display' => 'listings#display'
match 'listings/edit' => 'listings#edit'
match 'listings/update' => 'listings#update'

编辑:创建动作

def create

  @product = Product.new(params[:product])
  @product.user = current_user

  if @product.save
    redirect_to :action => 'index'
  end
end

【问题讨论】:

  • 什么是listings_update_path?它通向何方?显示此操作代码。通常是update_litings_path 或者甚至只是listings_pathPUT 方法
  • 这会导致上面显示的更新操作。 rake routes 告诉我它是 'listings_update_path'..
  • 为什么不遵循路由和命名约定?
  • 有一个很长的原因.. 这与编辑许多不同的模型必须在同一页面上完成这一事实有关。
  • 显示你的trace(其实只有importaint是paramshash)

标签: ruby-on-rails routes


【解决方案1】:

首先,对于在单个视图中编辑多个记录的替代方法,请尝试以下 railscast:http://railscasts.com/episodes/198-edit-multiple-individually

其次,这是非常规的,但你的整个方法是非常规的......

您可以在表单中粘贴hidden field,并在其中添加ID。比如:

<%= f.hidden_field, :product, :id %>

然后检查您的参数哈希,id 将在那里。您应该能够在控制器中使用类似于以下内容的方式访问它:

# untested
@edit = Product.find(params[:product][:id])

我不知道它将如何存储在您的 params 哈希中,但它会在那里,您将能够像访问任何其他哈希属性一样访问它。

祝你好运!

--编辑--

另外,关于您对 Rails 缺乏灵活性的评论——我了解到的一件事是 Rails 并非不灵活,但它针对特定约定进行了高度优化。开发人员将此称为“自以为是”的软件,这意味着:

  1. 它几乎可以做任何你想做的事情,但......
  2. 几乎总是有一种“首选”方式,即更好、更快(更难、更强,哈哈)。

阅读Beginning Rails 3 书,您会为自己节省大量时间和精力——并且可能会获得很多乐趣。你可以在一个周末完成它,当你完成后,你会有一个很好的“Rails Way”入门,希望能帮助你从“我不明白为什么 Rails 不做这个或那个”到“我了解 Rails 的工作原理以及遵循 X 模式做我想做的事情是多么容易”。无论如何,这就是发生在我身上的事情。

再次祝你好运!

【讨论】:

    【解决方案2】:

    试试这个

    <%= form_for @edit, :url => listings_path(@edit), :html => {:method => :put} do |f| %>
    

    【讨论】:

    • 您能在跟踪中看到任何id 吗?我不能。试试这个:listings_update_path(:id =&gt; @edit.id)
    • 因为你没有遵守约定:)。所以你的代码搞砸了
    • 发生了什么?展示下。我说 Ruby 比英语好 :)
    • 你试过了吗? &lt;%= form_for @edit, :url =&gt;listings_update_path(:id =&gt; @edit.id) %&gt;
    • 这可能是您的路线或其他任何问题。这里的主要问题是架构问题。
    【解决方案3】:

    您需要修复单个产品实例具有 id 的路由:

    match 'listings/index' => 'listings#index'
    match 'listings/:id/display' => 'listings#display'
    match 'listings/:id/edit' => 'listings#edit'
    match 'listings/:id/update' => 'listings#update'
    

    【讨论】:

    • 是的,我曾在某个阶段尝试过,但无济于事。这只是我的路线文件的当前状态。为了展示我尝试过的所有内容,StackOverflow 会占用整个服务器的硬盘
    • 并添加:as 选项。 match 'listings/:id/update' =&gt; 'listings#update', :as =&gt; listings_update ...
    • 当我这样做时,我没有收到任何错误,但检查数据库显示记录未更新。我尝试添加 :via => 'put' 但随后出现找不到路由错误。
    • 就像 fl00r 说的,如果你想在你的代码中引用listings_update_path,你需要添加:as =&gt; listings_update。如果路线中没有 :id,您将无法获得匹配的路线......所以您需要从那里开始。然后让我们知道什么不起作用。此外,您似乎没有通往 listings#create 操作的路线,因此您需要将其添加到。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-18
    • 2012-03-11
    • 2015-09-17
    • 2016-05-05
    • 2011-07-10
    相关资源
    最近更新 更多