Reputation: 175
I'm trying to make a table from 2 different sets of data
My Controller
@data = CompanyBorrower.find(params[:id])
@data1= @data.childs.all
@data2= @data.parents.all
The Table (a snippet)
<% @data1.zip(@data2) do |f1,f2| %>
<tr>
<td><%= f1.company_borrower1.name %></td>
<td><%= f2.company_borrower2.name %></td>
</tr>
<% end %>
But I get "undefined method `company_borrower2' for nil:NilClass". If I remove one or the other set of data it works fine.
I think I know the issue; I think it is because the "data1" returns 5 rows, whilst "data2" would have 1 row. If I switch, it works, but I only get one row!
So I (think) I know the issue, but have no idea how to resolve?
Edit - Updated
Note that company_borrower1 & company_borrower2 use the same model -
CompanyBorrower Model
has_many :childs, :class_name => 'Parent', :foreign_key => 'company_borrower_id'
has_many :parents, :class_name => 'Parent', :foreign_key => 'company_borrower_id1'
Parent Model
belongs_to :company_borrower1, :class_name => 'CompanyBorrower', :foreign_key => :company_borrower_id
belongs_to :company_borrower2, :class_name => 'CompanyBorrower', :foreign_key => :company_borrower_id1
UPDATE 2
If I do the following it works great, but it places what would be columns across rows. I can work with that, but would still prefer to know how to achieve my original question for future reference
<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>
Upvotes: 0
Views: 345
Reputation: 194
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 %>
Upvotes: 2
Reputation: 121000
My wild guess would be to use try
on what’s returned. So instead of this:
<td><%= data1.name %></td>
<td><%= data2.name %></td>
You should do something like:
<td><%= data1.try(:name) %></td>
<td><%= data2.try(:name) %></td>
Upvotes: 0