Rails嵌套属性被复制 [英] Rails Nested attributes being duplicated

查看:93
本文介绍了Rails嵌套属性被复制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题困扰了我.我整个周末都在这儿,但不知道发生了什么事.

This problem has beaten me. I've been at it all weekend but can't figure out what is happening.

当我创建一个新的employee对象时,我还想在我的employee模型中使用accepts_nested_attributes_for :ee_pay创建多个新的ee_pay记录.

When I create a new employee object, I also want to create multiple new ee_pay records using accepts_nested_attributes_for :ee_pay in my employee model.

为新员工创建ee_pay记录取决于该员工所属公司存在的company_pay对象的数量.因此,在下面的情况下,有2个company_pay对象->基本" [id:2]和时间+ 1/2" [id:3](在before_action中返回),我想创建一个针对上述员工中的每一个

Creation of ee_pay records for new employees is dependent on the amount of company_pay objects that exist for the company that the employee belongs to. So in the case below there's 2 company_pay objects -> "Basic" [id:2] and "Time + 1/2" [id:3] (returned in the before_action) and I want to create an ee_pay for each of these for the employee in question

这是代码:-

employees_controller.rb

 before_action :set_company_pay_types, only: [:new, :update, :edit]

        def new
            @ee_pay_types = []
            @taxable_pays.each do |pt|
              @ee_pay_types << @employee.ee_pay.build(company_pay_id: pt.id)
            end
        end                 

        private
          def set_company_pay_types
              @taxable_pays = CompanyPay.where(['company_id = ? AND pay_sub_head_id = ? AND description <> ?', current_company.id, 1, "Salary"]).order(:id)
          end

          def employee_params
            params.require(:employee).permit(....[multiple other fields]..., address_attributes:[:id, :line1, :line2, :line3, :line4, :postcode, :country], ee_pay_attributes:[:id, :employee_id, :company_pay_id, :amount, :rate])
          end

视图/员工/表单

<div><strong>Hourly Pay Types</strong></div>
<div class="form_spacer"></div>
<div class="row">
   <div class="col-md-3">  
      <div class="form_indent1"><div class="form_label"><strong>Description</strong></div></div>           
   </div> 
   <div class="col-md-3">  
      <div class="form_indent1"><div class="form_label"><strong>Amount</strong></div></div>           
   </div>
   <div class="col-md-2">  
      <div class="form_indent1"><div class="form_label"><strong>Units</strong></div></div>           
   </div>                
   <div class="col-md-4">  
      <div class="form_indent1"><div class="form_label"><strong>Rate</strong></div></div>           
   </div> 
   <div>
             <%= debug @ee_pay_types %> 
             <% @ee_pay_types.each do |ee_pay| %>
                 <%= f.fields_for :ee_pay do |builder| %>                                   
                 <%= builder.hidden_field :company_pay_id %>     
                 <div class="col-md-3">
                     <div class="form_indent1"><div class="form_indent1"><%= ee_pay.company_pay.description %></div></div>
                     <div class="form_spacer"></div>
                 </div> 
                 <div class="col-md-3">
                     <div class="form_indent1"><%= builder.text_field :amount, class: "number_input" %></div>
                     <div class="form_spacer"></div>
                 </div>  
                 <div class="col-md-2">
                     <div class="form_indent1"><%= ee_pay.company_pay.units %></div>
                     <div class="form_spacer"></div>
                 </div>  
                 <div class="col-md-4">  
                     <div class="form_indent1"><%= builder.text_field :rate, class: "number_input" %></div>
                     <div class="form_spacer"></div><br />
                 </div>                             

                 <% end %> 
             <% end %> 
   </div> 
   </div>

员工的产出/新

当我创建新的员工记录时,我得到ee_pay对象的以下输出.事实证明,代码正在以以下格式复制每个代码:-

When I go to create a new employee record, I'm getting the following output for the ee_pay objects. It turns out the code is duplicating each one in the following format:-

*description*        *company_pay_id*    
Basic                   2
Basic                   3
Time & 1/2              2
Time & 1/2              3

在我看来,employees_controller中的这行@ee_pay_types << @employee.ee_pay.build(company_pay_id: pt.id)正在构建两个新的ee_pay对象(在上图中的调试中输出).然后在视图中,它遍历这两个对象,并为每个对象创建两个新的ee_pay对象.我认为这是正在发生的事情,但我可能会完全绞尽脑汁.我在这个阶段迷路了,不知道如何解决.

It looks to me like this line @ee_pay_types << @employee.ee_pay.build(company_pay_id: pt.id) in the employees_controller is building two new ee_pay objects (that are output in the debug in the picture above). Then in the view, it's iterating over these two and for each one, creating two new ee_pay objects. I think this is what's happening but I could be completely wring. I'm lost at this stage and I've no idea how to fix it.

希望有人能为我指出正确的解决方法.我可能很明显很想念.

Hopefully, someone can point me in the right direction on how to solve it. It's probably something very obvious that I'm missing.

感谢您的关注

编辑1

根据要求添加模型

型号/ee_pay

    class EePay < ActiveRecord::Base
        belongs_to :employee
        belongs_to :company_pay
    end

型号/公司付款

    class CompanyPay < ActiveRecord::Base
        belongs_to :pay_sub_head
        belongs_to :company
        has_many :ee_pay
    end

模型/员工

    class Employee < ActiveRecord::Base
        belongs_to :company
        belongs_to :address
        accepts_nested_attributes_for :address
        has_many :ee_pay
        accepts_nested_attributes_for :ee_pay
    end

Yann在评论中建议将employee_controller更改为此

Yann suggested in the comments changing the employee_controller to this

    @ee_pay_types = []
    @taxable_pays.each do |pt|
        @employee.ee_pay.build(company_pay_id: pt.id)
    end

并删除视图中@ee_pay_types的迭代,现在看起来像(我将对ee_pay的任何引用都更改为builder):-

and removing the iteration over @ee_pay_types in the view, which now looks like (I changed any reference to ee_pay to builder):-

    <div>
            <%= debug @ee_pay_types %>  
            <%= f.fields_for :ee_pay do |builder| %>                                    
                <%= builder.hidden_field :company_pay_id %>     

                <div class="col-md-3">
                    <div class="form_indent1"><div class="form_indent1"><%= builder.company_pay.description %></div></div>
                    <div class="form_spacer"></div>
                </div> 
                    <div class="col-md-3">
                    <div class="form_indent1"><%= builder.text_field :amount, class: "number_input" %></div>
                    <div class="form_spacer"></div>
                </div>  
                    <div class="col-md-2">
                    <div class="form_indent1"><%= builder.company_pay.units %></div>
                    <div class="form_spacer"></div>
                </div>  
                    <div class="col-md-4">  
                    <div class="form_indent1"><%= builder.text_field :rate, class: "number_input" %></div>
                    <div class="form_spacer"></div><br />
                </div>
            <% end %> 
    </div> 

但这给了我错误:-

undefined method `company_pay' for #<ActionView::Helpers::FormBuilder:0x007f47d5649118>

在我看来,我无法访问正在创建的ee_paycompany_pay.任何想法吗?

To me it looks like I can't access the company_pay of the ee_pay being created. Anyone any ideas?

编辑2-已解决

在进行了Yan Foto建议的编辑后,我便可以访问使用builder.object.company_pay.description创建的ee_paycompany_pay.再次感谢Yan.

After making the edits suggested by Yan Foto, I was then able to access the company_pay of the ee_pay being created using builder.object.company_pay.description. Thanks again Yan.

推荐答案

您无需在

You don't need to iterate before fields_for since it renders your form for the number of existing associations. You can confirm this by changing the number of @taxable_pays to 3 and see how you get 9 (and not 6) items in your form.

将您的控制器更改为以下内容:

Change your controller to the following:

def new
  @ee_pay_types = []
  @taxable_pays.each do |pt|
    @employee.ee_pay.build(company_pay_id: pt.id)
  end
end

并从表单中删除<% @ee_pay_types.each do |ee_pay| %>,您就很好了.

and remove <% @ee_pay_types.each do |ee_pay| %> from your form and you're good to go.

更新 您还希望以以下形式访问CompanyPay:

builder.object使您可以访问表单对象(EePay实例),调用builder.object.company_pay.description可以为相关的CompanyPay提供描述.

builder.object gives you access to the form object (EePay instance) and calling builder.object.company_pay.description gives you the description of the associated CompanyPay.

这篇关于Rails嵌套属性被复制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆