mfanto
mfanto

Reputation: 14418

RoR foreign key inside view and nil object

I'm working through Agile Web Development with Rails and having a problem with Task E and adding the payment types to a database. Within the orders table, there is a foreign key relating the column payment_type_id to the payment_types database (which holds columns id, label and value)

So, an order has a payment_type_id of 1, which corresponds to the entry in payment_types of "Credit Card", "cc"

class Order < ActiveRecord::Base
has_many :line_items
belongs_to :payment_types


class PaymentType < ActiveRecord::Base
has_one :order

Then within the Order controller

class OrdersController < ApplicationController
  # GET /orders
  # GET /orders.xml
  def index
    @orders = Order.all

And then in the index.html.erb view:

<% @orders.each do |order| %>
  <tr>
    <td><%=h order.name %></td>
    <td><%=h order.payment_types.label %></td>

This gives the following error:

"You have a nil object when you didn't expect it! The error occurred while evaluating nil.label"

for the line order.payment_types.label

Do I have the relationships correct? The foreign key works elsewhere, when creating orders and everything. It's just in this view. Thanks so much for any help.

Upvotes: 0

Views: 195

Answers (1)

cwninja
cwninja

Reputation: 9778

Side note: Your belongs_to :payment_types should be belongs_to :payment_type. You only have one payment type for any given order.

This will be because this specific order has no payment type (order.payment_types is nil).

To fix this, you can do:

<td><%=h order.payment_type.label if order.payment_type %></td>

or even

<td><%=h order.payment_type.try(:label) %></td>

which does much the same thing, but uses some rails kung-fu (some purists will whine about this as a code smell, but they can all stop whining and do something useful, like building a shed).

or you can set the payment type some how (possibly involving a more complex controller, and maybe a validates_presence_of :payment_type in your Order model.

Upvotes: 3

Related Questions