首页 > 解决方案 > Array#zip 不工作(nil:NilClass 的未定义方法)

问题描述

我正在尝试从 2 组不同的数据中创建一个表格

我的控制器

@data = CompanyBorrower.find(params[:id])
@data1= @data.childs.all
@data2= @data.parents.all

表(片段)

            <% @data1.zip(@data2) do |f1,f2| %>
              <tr>
                <td><%= f1.company_borrower1.name %></td>
                <td><%= f2.company_borrower2.name %></td>
              </tr>
            <% end %>

但我得到“nil:NilClass 的未定义方法 `company_borrower2'”。如果我删除一个或另一组数据,它工作正常。

我想我知道这个问题;我认为这是因为“data1”返回 5 行,而“data2”将有 1 行。如果我切换,它可以工作,但我只能得到一排!

所以我(想)我知道这个问题,但不知道如何解决?

编辑 - 更新

请注意, company_borrower1 和 company_borrower2 使用相同的模型 -

公司借款人模式

has_many :childs, :class_name => 'Parent', :foreign_key => 'company_borrower_id'
has_many :parents, :class_name => 'Parent', :foreign_key => 'company_borrower_id1'

父模型

belongs_to :company_borrower1, :class_name => 'CompanyBorrower', :foreign_key => :company_borrower_id
belongs_to :company_borrower2, :class_name => 'CompanyBorrower', :foreign_key => :company_borrower_id1

更新 2

如果我执行以下操作,效果很好,但它会将列放置在行之间。我可以使用它,但仍然希望知道如何实现我原来的问题以供将来参考

              <tr>
                <% @data1.each do |f1| %><td><%= f1.company_borrower1.name %></td><% end %>
              </tr>
              <tr>
                <% @data2.each do |f1| %><td><%= f1.company_borrower2.name %></td><% end %>
              </tr>

标签: ruby-on-railsruby

解决方案


if you are using ruby 2.3 or greater version you can make use of Safe navigation operator (&.) instead of try method

        <% @data1.zip(@data2) do |f1,f2| %>
          <tr>
            <td><%= f1&.company_borrower1&.name %></td>
            <td><%= f2&.company_borrower2&.name %></td>
          </tr>
        <% end %>

The safe navigation operator (&.) will return nil if the object equals nil, otherwise it calls the method on the object..So, if you use the safe navigation operator, you need to make sure it will be called on the all methods.For example, I have used safe navigation operator on f2 object , f2&.company_borrower2 will return nil,but here we are calling agin name method on the return value of f2&.company_borrower2.So in oreder to avoid the error, we need to call agian safe navigation operator.

Same thing applies on the usage of try method

       <% @data1.zip(@data2) do |f1,f2| %>
          <tr>
            <td><%= f1.try(:company_borrower1).try(:name) %></td>
            <td><%= f2.try(:company_borrower2).try(:name) %></td>
          </tr>
        <% end %>

推荐阅读