Rails 中的嵌套表单问题:Show 中的 NoMethodError

发布于 2024-09-03 07:50:53 字数 2964 浏览 8 评论 0原文

我正在尝试构建一个简单的产品积压应用程序来自学 Rails。对于每个产品,可以有多个产品待办事项条目,因此我想创建一个产品视图,显示产品信息、产品的所有待办事项条目,并包括用于添加更多待办事项条目的嵌套表单。

一切正常,直到我尝试将表单添加到视图中,然后导致以下错误:

NoMethodError in Products#show

Showing app/views/products/show.html.erb where line #29 raised:

undefined method `pblog_ref' for #<Product:0x10423ba68>
Extracted source (around line #29):

26:   <%= f.error_messages %>
27:   <p>
28:     <%= f.label :pblog_ref %><br />
29:     <%= f.text_field :pblog_ref %>
30:   </p>
31:   <p>
32:     <%= f.label :product %><br />

报告问题的产品视图如下(部分工作正常,所以我不会包含该代码):

<h1>Showing product</h1>

<p>
  <b>Product ref:</b>
  <%=h @product.product_ref %>
</p>
<p>
  <b>Description:</b>
  <%=h @product.description %>
</p>
<p>
  <b>Owner:</b>
  <%=h @product.owner %>
</p>
<p>
  <b>Status:</b>
  <%=h @product.status %>
</p>

<h2>Product backlog</h2>
<div id="product-backlog">
  <%= render :partial => @product.product_backlogs %>
</div>

<% form_for(@product, ProductBacklog.new) do |f| %>
  <%= f.error_messages %>
  <p>
    <%= f.label :pblog_ref %><br />
    <%= f.text_field :pblog_ref %>
  </p>
  <p>
    <%= f.label :product %><br />
    <%= f.text_field :product %>
  </p>
  <p>
    <%= f.label :description %><br />
    <%= f.text_field :description %>
  </p>
  <p>
    <%= f.label :owner %><br />
    <%= f.text_field :owner %>
  </p>
  <p>
    <%= f.label :status %><br />
    <%= f.text_field :status %>
  </p>
  <p>
    <%= f.submit 'Create' %>
  </p>
<% end %>

<%= link_to 'Edit', edit_product_path(@product) %> |
<%= link_to 'Back', products_path %>

这是产品模型:

class Product < ActiveRecord::Base
  validates_presence_of :product_ref, :description, :owner
  has_many :product_backlogs
end

这是 ProductBacklog 模型:

class ProductBacklog < ActiveRecord::Base
  belongs_to :product
end

这些是路线:

  map.resources :product_backlogs
  map.resources :products, :has_many => :product_backlogs

该模型的架构中存在所有列:

create_table "product_backlogs", :force => true do |t|
  t.string   "pblog_ref"
  t.integer  "product_id"
  t.string   "description"
  t.string   "owner"
  t.string   "status"
  t.datetime "created_at"
  t.datetime "updated_at"
end

我已经根据 使用 Rails 2 screencast 在 15 分钟内创建一个博客,原则上我似乎在做与他相同的事情 - 只有他的嵌套评论表单有效,而我的不行!

我希望在我发疯之前有人能帮忙解决这个问题!我确信这是一件微不足道的事情。

I'm trying to build a simple product backlog application to teach myself Rails. For each product, there can be multiple product backlog entries, so I want to create a product view that shows the product information, all the backlog entries for the product, and includes a nested form for adding more backlog entries.

Everything works until I try to add the form to the view, which then results in the following error:

NoMethodError in Products#show

Showing app/views/products/show.html.erb where line #29 raised:

undefined method `pblog_ref' for #<Product:0x10423ba68>
Extracted source (around line #29):

26:   <%= f.error_messages %>
27:   <p>
28:     <%= f.label :pblog_ref %><br />
29:     <%= f.text_field :pblog_ref %>
30:   </p>
31:   <p>
32:     <%= f.label :product %><br />

The product view where the problem is reported is as follows (the partial works fine, so I won't include that code):

<h1>Showing product</h1>

<p>
  <b>Product ref:</b>
  <%=h @product.product_ref %>
</p>
<p>
  <b>Description:</b>
  <%=h @product.description %>
</p>
<p>
  <b>Owner:</b>
  <%=h @product.owner %>
</p>
<p>
  <b>Status:</b>
  <%=h @product.status %>
</p>

<h2>Product backlog</h2>
<div id="product-backlog">
  <%= render :partial => @product.product_backlogs %>
</div>

<% form_for(@product, ProductBacklog.new) do |f| %>
  <%= f.error_messages %>
  <p>
    <%= f.label :pblog_ref %><br />
    <%= f.text_field :pblog_ref %>
  </p>
  <p>
    <%= f.label :product %><br />
    <%= f.text_field :product %>
  </p>
  <p>
    <%= f.label :description %><br />
    <%= f.text_field :description %>
  </p>
  <p>
    <%= f.label :owner %><br />
    <%= f.text_field :owner %>
  </p>
  <p>
    <%= f.label :status %><br />
    <%= f.text_field :status %>
  </p>
  <p>
    <%= f.submit 'Create' %>
  </p>
<% end %>

<%= link_to 'Edit', edit_product_path(@product) %> |
<%= link_to 'Back', products_path %>

This is the Product model:

class Product < ActiveRecord::Base
  validates_presence_of :product_ref, :description, :owner
  has_many :product_backlogs
end

This is the ProductBacklog model:

class ProductBacklog < ActiveRecord::Base
  belongs_to :product
end

These are the routes:

  map.resources :product_backlogs
  map.resources :products, :has_many => :product_backlogs

All the columns exist in the schema for this model:

create_table "product_backlogs", :force => true do |t|
  t.string   "pblog_ref"
  t.integer  "product_id"
  t.string   "description"
  t.string   "owner"
  t.string   "status"
  t.datetime "created_at"
  t.datetime "updated_at"
end

I've checked what I'm doing against the Creating a weblog in 15 minutes with Rails 2 screencast, and in principle I seem to be doing the same thing as him - only his nested comments form works, and mine doesn't!

I hope someone can help with this, before I turn mad! I'm sure it's something trivial.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

二货你真萌 2024-09-10 07:50:53

检查您的数据库,也许某些迁移失败,并且您只有部分字段,

您也可以先运行脚本/控制台进行检查,然后发出“p Product.new” 。它将向您显示一个包含所有已知字段的空 Product 对象,例如:

#./script/console
Loading development environment (Rails 2.3.5)
>> p User.new
#<User id: nil, type: nil, login: nil, name: "", email: nil, crypted_password: nil, salt: nil, created_by_id: nil, created_at: nil, updated_at: nil, remember_token: nil, remember_token_expires_at: nil, male: true, dept_id: nil, deleted: nil>
=> nil

check your database, maybe some migration failed and you have only part of fields there

you can also check with running script/console first, and then issuing "p Product.new". It will show you an empty Product object with all known fields, like:

#./script/console
Loading development environment (Rails 2.3.5)
>> p User.new
#<User id: nil, type: nil, login: nil, name: "", email: nil, crypted_password: nil, salt: nil, created_by_id: nil, created_at: nil, updated_at: nil, remember_token: nil, remember_token_expires_at: nil, male: true, dept_id: nil, deleted: nil>
=> nil
凯凯我们等你回来 2024-09-10 07:50:53

您的模型中似乎没有 pblog_ref 字段。查看创建了 products 表的迁移,是否有 pblog_ref 字段?

编辑:
好吧,这行似乎是错误的:

<% form_for(@product, ProductBacklog.new) do |f| %>

它为您的 @product 创建表单,而不是为 ProductBacklog.new 创建表单。尝试:

<% form_for(ProductBacklog.new) do |f| %>

我总是对某些嵌套模型的 form_for 参数有问题,因此我更喜欢使用 accepts_nested_attributes_for,然后使用 fields_for 创建子对象。

在您的情况下, form_for 应该如下所示:

<% form_for ProductBacklog.new, :url => new_product_product_backlog_path(@product) do |f| %>

但是我没有检查它,它可能是错误的(正如我所说,我总是对这些路径有问题)。

It seems that you don't have pblog_ref field in your model. Take a look into migration that created products table, is there pblog_ref field?

EDIT:
Ok, it seems that this line is wrong:

<% form_for(@product, ProductBacklog.new) do |f| %>

It creates form for your @product not for ProductBacklog.new. Try:

<% form_for(ProductBacklog.new) do |f| %>

I always have problems with form_for arguments with some nested models, so I prefer using accepts_nested_attributes_for and then creating subobjects with fields_for.

In your case form_for should look like this:

<% form_for ProductBacklog.new, :url => new_product_product_backlog_path(@product) do |f| %>

However I didn't check it and it probably is wrong (as I said I always have problems with those paths).

无声静候 2024-09-10 07:50:53

解决方案是将行: 替换

<% form_for(@product, ProductBacklog.new) do |f| %>

为:

<% form_for [@product, ProductBacklog.new] do |f| %>

注意 form_for 后面的空格和方括号。

The solution was to replace the line:

<% form_for(@product, ProductBacklog.new) do |f| %>

with:

<% form_for [@product, ProductBacklog.new] do |f| %>

Note the space after form_for, and the square brackets.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文