嵌套属性子模型不保存

时间:2016-03-31 18:48:14

标签: ruby-on-rails ruby hash

我在使用嵌套属性保存的模型中遇到问题。 在应用程序中,有客户,其中有1..n 联系人女巫依次拥有1..n 电话。< / p>

我在问这里之前已经进行了很多搜索,并决定先将其保存为 Contact 。好吧,首先存储 Customer ,但不存储 Contact 。根据我的阅读,无需在创建中的函数中重复 ... contacts.build ,并且 &#34; @customer = Customer.new(customer_params)&#34; 这一行会创建并存储它们。

为什么它不起作用? (这是第一个问题。)

经过一些修改和调试后,我发现当我设置第二行建立联系人( ... contacts.build(customer_params [:contacts_attributes]) )时,它&由于“未知属性”错误,未保存#39;这是因为在hash:contacts_attribute和它的内容之间,它添加了另一个哈希,称为&#39;:0&#39; (?)。来自表单的哈希结构如下:

&#34;:contacts_attribute [:0 [:name,:department,:email]]&#34;

我想这个哈希:0用于添加多个 Contact 实例,它将包含哈希:1,:2等。

有一种方法来存储 Contact 实例,方法是获取:0哈希? (如何访问此哈希?是 &#34; ...:contacts_attribute [0]&#34; ?)

以下是相关代码。 感谢您的关注!

customer.rb

class Customer < ActiveRecord::Base
...    
has_many :contacts
accepts_nested_attributes_for :contacts, reject_if: lambda {|attributes| attributes['kind'].blank?}
... 
def change_by(user_id)
  update_attributes(changed_by: user_id, deleted_at: Time.now, updated_at: Time.now)
end

def delete(user_id)
  update_attributes(status: false, changed_by: user_id, deleted_at: Time.now, updated_at: Time.now)
end

private
...
end

customers_controller.rb

class CustomersController < ApplicationController 

def new
  @customer = Customer.new
  @customer.contacts.new
end

def create
  user_id = session[:user_id]
  @customer = Customer.new(customer_params)
  if @customer.save
    @customer.change_by(user_id)
    flash[:success] = "Cliente cadastrado com sucesso!"
    redirect_to customers_url
  else
    render 'new'
  end
end

private

def customer_params
  params.require(:customer).permit(:razao_social, :nome, :CPF_CNPJ,
              :adress_id, :email_nota, :transporter_id, :observacao, 
              contacts_attributes: [:nome, :setor, :email])
end

表格

<div class="row">
<div class="col-md-6 col-md-offset-3">
  <%= form_for @customer do |f| %>
    <%= f.label "Dados Básicos" %>
    <div class="well">      
    <%= f.label :razao_social, "Razão Social" %>
    <%= f.text_field :razao_social %>

    <%= f.label :nome, "Nome" %>
    <%= f.text_field :nome %>

    <%= f.label :CPF_CNPJ, "CPF/CNPJ" %>
    <%= f.text_field :CPF_CNPJ %>

    <%= f.label :email_nota, "Email para nota" %>
    <%= f.email_field :email_nota %>

    <%= f.label :observacao, "Observações" %>
    <%= f.text_area :observacao %>
    </div>

    <%= f.fields_for :contacts do |k| %>
      <%= k.label "Contato" %>
      <div class="well">   
        <%= k.label :nome, "Nome" %>
        <%= k.text_field :nome %>

        <%= k.label :setor, "Setor" %>
        <%= k.text_field :setor %>

        <%= k.label :email, "Email" %>
        <%= k.email_field :email %>

      </div>   
    <% end %>
    <%= f.submit "Cadastrar Cliente", class: "btn btn-primary" %>
  <% end %>
</div>

1 个答案:

答案 0 :(得分:0)

reject_if: lambda {|attributes| attributes['kind'].blank?}

表单中没有:kindcustomer_params

的迹象

这可能与它有关。

除此之外,如果您需要为联系人添加/删除关系,请查看cocoon gem。如果您只需要一个,那么将其构建到您的字段中:

<%= f.fields_for :contacts, @customer.contacts.first || @customer.contacts.build do |k| %>

然后,表单将特定于单个联系实例。

  

有一种方法可以通过获取:0哈希来存储Contact实例吗?   (如何访问此哈希?是“...:contacts_attribute [0]”?)

您无需访问它,这就是accepts_nested_attributes的用途。其余代码看起来没问题,所以在顶部排除拒绝问题,如果仍然存在问题则返回,并发布日志输出 - 特别是请求的params哈希!