代码之家  ›  专栏  ›  技术社区  ›  Adam Lassek

为什么这个呈现:部分行重复我的集合两次?

  •  1
  • Adam Lassek  · 技术社区  · 15 年前

    考虑到这些关系:

    class Account < ActiveRecord::Base
      has_many :employments
      has_many :people, :through => :employments
      accepts_nested_attributes_for :employments
    end
    
    class Employment < ActiveRecord::Base
      belongs_to :account
      belongs_To :person
    end
    

    我想列出一个账户的就业记录:

    <% form_for @account do |f| -%>
      <% f.fields_for :employments do |e| -%>
        <%= render :partial => 'employment', :collection => @account.employments, :locals => { :f => e } %>
      <% end -%>
    <% end -%>  
    

    我已经验证@account中的就业表包含两个记录,但我得到了部分的四个副本,因为它重复两次就业:

    Employment Load (1.0ms)   SELECT * FROM [employments] WHERE ([employments].account_id = 1) 
    Person Load (1.3ms)   SELECT * FROM [people] WHERE ([people].[id] = 2) 
    Rendered accounts/_employment (17.9ms)
    Person Load (1.5ms)   SELECT * FROM [people] WHERE ([people].[id] = 1) 
    Rendered accounts/_employment (5.1ms)
    Rendered accounts/_employment (2.2ms)
    Rendered accounts/_employment (2.1ms)
    

    有人能解释为什么会这样吗?


    以下是一些附加信息:

    这个 _employment.html.erb 部分:

    <div class="employment">
      <span class="name"><%= link_to h(employment.person.name), person_path(employment.person) %></span>
      <span class="role"><%=h employment.role %></span>
      <span class="commands"><%= remove_child_link "Remove", f %></span>
    </div>
    

    remove_child_link 是唯一需要生成表单域的位置。它创造了 _delete 记录的字段并连接一个将值更改为“1”的删除链接。“role”属性也可以编辑。重要的是,我不希望所有字段都可编辑。

    这个 accounts_controller 此视图的操作:

    def edit
      @account = Account.find(params[:id])
    end
    
    def update
      @account = Account.find(params[:id])
    
      respond_to do |format|
        if @account.update_attributes(params[:account])
          flash[:notice] = "#{@account.business_name} was successfully updated."
          format.html { redirect_to @account }
        else
          format.html { render :action => "edit" }
        end
      end
    end
    

    本让我走对了方向。一些运行时检查显示记录存储在 object 变量(我已经知道,但在另一个上下文中)。所以我可以重写 fields_for 条款如下:

    <% form_for @account do |f| -%>
      <% f.fields_for :employments do |e| -%>
        <div class="employment">
          <span class="name"><%= link_to h(e.object.person.name), person_path(e.object.person) %></span>
          <span class="role"><%=h e.object.role %></span>
          <span class="commands"><%= remove_child_link "Remove", e %></span>
        </div>
      <% end -%>
    <% end -%>
    
    2 回复  |  直到 15 年前
        1
  •  1
  •   Ben    15 年前

    你用得对 fields_for ,但它将为每个 employment ,所以移除 :collection 参数从 render :partial . 相反,使用嵌套表单,将其放入您的帐户模型中:

    accepts_nested_attributes_for :employments
    

    阅读此处有关嵌套表单的详细信息: http://ryandaigle.com/articles/2009/2/1/what-s-new-in-edge-rails-nested-attributes

        2
  •  3
  •   Cody Caughlan    15 年前

    它为“雇用”模型中的每个字段呈现该部分-当确实要为每个雇用记录执行一次时。也就是说,删除字段\上的迭代:

    <% form_for @account do |f| -%>
       <%= render :partial => 'employment', :collection => @account.employments %>
    <% end -%>