如何传递对象ID?

时间:2011-04-19 16:19:21

标签: ruby-on-rails

我有两个模特之间的关系

类别模型

class Category < ActiveRecord::Base
   belongs_to :product
end

产品型号

class Product < ActiveRecord::Base
  has_many :categories
end

我在产品表中有category_id但在我的产品表中创建新产品时 category_id为空。我是钢铁新手,任何人都可以帮忙吗?

2 个答案:

答案 0 :(得分:4)

首先,一个想法 - 大多数时候,产品有很多类别,但每个类别也包含很多产品。也许你的协会应该是多对多的?关于你的实际问题。

如果我理解正确,您的问题实际上是关于如何创建数据库中彼此相关的类别和产品,即如何在构建新类别时设置product_id的值。

为了清楚您需要它,product_id只能为类别设置。毕竟,该类别属于该产品,因此必须保留其所有者的ID。

因此,假设您要构建属于现有产品的新类别 - 您可以这样做:

# in your view, where you link from products/show.html.erb to category/new.html.erb
<%= link_to "Build new category for this product", new_category_url(:id => @product.id) %>
    # you must have @product defined, and you also must have 
    # 'resources :categories' in your routes file

# in your controller action categories/new, set the new category's product id:
def new
  @category = Category.new(:product_id => params[:id])
end

# include a hidden field to contain the product_id in your new form
<%= form_for @category do |f| %>
  <%= f.hidden_field :product_id %>
  ... other fields, labels, etc.
<% end %>

# save the record as you normally would (analogous to the code in your comment to @Chowlett).
@category = Category.new(params[:category])
if @category.save
  redirect_to :action => "list", :notice => "Category saved successfully."
else
  render :action => "new"
end

上面的代码允许您逐个构建产品,然后是每个类别。因此,我们首先构建您的产品,然后包括从产品/展示页面到您的类别/新表单的链接,并传递您希望该类别成为其中一部分的产品的ID。

如果您想同时构建产品和某些类别 ,则会更复杂一些。有关此问题的更多信息,请查看http://railscasts.com/episodes/196-nested-model-form-part-1(这是三部曲系列中的第一部分)和https://github.com/ryanb/nested_form。除非您对以上基础知识非常满意,否则我不建议采取这种行动。当我刚接触Rails时,我曾经在这段代码中陷入困境一周!

答案 1 :(得分:3)

首先,您在错误的表格中有_id字段。如果是Category belongs_to :product,那么您的类别表需要一个字段product_id

以这种方式看待:每个产品都可以有多个类别 - 那么您期望在category_id字段中找到单个值?

如果您在纠正后仍有问题,请与我联系。

编辑:一旦设置了表格,您仍然需要告诉Rails链接应该是什么。你有几个选择。假设您手头有一个类别,最好的选择是new_prod = my_cat.create_product()。或者,您可以使用new_prod = Product.create(:category => my_cat)

稍后,您可以将模型关联在一起,如下所示:

my_prod.category = my_cat
my_prod.save