2014-12-03 75 views
1

我正在创建一个来自不同模型的属性的嵌套表单。我希望在保存新对象之前,所有必需的属性都是有效的。Rails - 如何验证具有嵌套属性的表单?

<%= form for @product do |f| %> 

    <%= f.fields_for @customer do |g| %> 

    <%= g.label :name %> 
    <%= g.text_field :name %> 

    <%= g.label :email %> 
    <%= g.text_field :email %> 

    <%= g.label :city %> 
    <%= g.text_field :city %> 

    <%= g.label :state %> 
    <%= g.text_field :state %> 

    <%= g.label :zipcode %> 
    <%= g.text_field :zipcode %> 

    <% end %> 

    <%= f.label :product %> 
    <%= f.text_field :product %> 

    <%= f.label :quantity %> 
    <%= number_field(:quantity, in 1..10) %> 

<% end %> 

这里是我的模型

class Product < ActiveRecord::Base 

    belongs_to :customer 
    validates_associated :customer 
    validates :product, :presence => "true" 

end 

class Customer < ActiveRecord::Base 

    has_one :product 
    validates :name, :email, presence: true 
    validates :email, format: { with: /[A-Za-z\d+][@][A-Za-z\d+][.][A-Za-z]{2,20}\z/ }    
    validates :city, presence: true 
    validates :zipcode, format: { with: /\A\d{5}\z/ } 

end 

我加validates_associated我的产品型号,所以我的form_for @product应该要求所有的客户验证通过。这意味着名称,电子邮件,城市和邮政编码必须在那里,并且必须正确格式化。

我乱了一下,提交了表格,没有填写客户要求的字段,表格被认为是有效的。

我不明白我的错误在哪里。

编辑

好了,所以加入validates :customer,现在需要的客户属性。但它们实际上并未保存到数据库中。我认为这与我的参数有关

def product_params 
    params.require(:product).permit(:product, :quantity) 
end 

是否需要将我的客户参数添加到我的允许参数列表中?

回答

2

尝试了这一点:

在控制器如下创建产品的实例和相关的客户:

@product = Product.new 
    @customer = @product.build_customer 

在使用这种代码形式

<%= form for @product do |f| %> 

    <%= f.fields_for :customer do |g| %> 

    <%= g.label :name %> 
    <%= g.text_field :name %> 

    <%= g.label :email %> 
    <%= g.text_field :email %> 

    <%= g.label :city %> 
    <%= g.text_field :city %> 

    <%= g.label :state %> 
    <%= g.text_field :state %> 

    <%= g.label :zipcode %> 
    <%= g.text_field :zipcode %> 

    <% end %> 

    <%= f.label :product %> 
    <%= f.text_field :product %> 

    <%= f.label :quantity %> 
    <%= number_field(:quantity, in 1..10) %> 

<% end %> 

我。e使用:客户符号而不是@customer实例变量。

和使用产品型号accepts_nested_attributes_for辅助方法@Charles说

3

如果对象存在的validates_associated方法只验证关联的对象,因此,如果您离开表单字段为空,则Product正在创建/编辑将验证,因为没有相关的Customer

相反,假设您使用的是Rails 4+,则需要使用accepts_nested_attributes_for :customer以及validates :customer, presence: true以便在您的产品表单中要求客户字段。

如果您使用的是Rails 3,那么accepts_nested_attributes_for将不适用于belongs_to关联。相反,您的Customer课程将需要使用accepts_nested_attributes_for :product,您需要相应地更改表单视图。

UPDATE

你也需要让你的控制器动作来接受参数为:customer协会:

def product_params 
    params.require(:product).permit(:product, :quantity, :customer_attributes => [:name, :email, :city, :state, :zipcode]) 
end 

值得一提的是,因为在你的客户表单字段没有:id场,并且在产品表单字段中没有:customer_id字段,则每次成功提交产品表单时都会创建一个新客户。

+0

OK,我尝试添加'验证:customer'现在需要的那场。但是当我输入字段时,它说它缺失。这一定是因为我的参数。我会看看我能否解决这个问题 – Darkmouse 2014-12-03 04:28:42