Noah Clark
Noah Clark

Reputation: 8131

has_one any different than has_many?

I have two models:

class Product < ActiveRecord::Base
  attr_accessible :amount, :name, :unit, :description, :stock, :limit
  has_many :cart_rows
  has_one :inquery
end

and

class Inquery < ActiveRecord::Base
  attr_accessible :product, :text, :phone, :zip, :product_id, :state, :street, :city
  belongs_to :product
end

In my index of Inqueries view I have:

<% @inqueries.each do |inquery| %>
  <%= inquery.product.name %>
  <%= inquery.text %>
<% end %>

And I get the following error: undefined method 'name' for nil:NilClass

What am I doing wrong? Does has_one behave differently than has_many?

Upvotes: 1

Views: 106

Answers (3)

Robin
Robin

Reputation: 21894

No, you should be able to call inquery.product. You probably have an inquery with no product.

In the console (rails c), run: Inquery.where(product_id: nil), and see if you get results.

You should validate the presence of the product, in the Inquery model:

validates :product, presence: true

Upvotes: 2

JD.
JD.

Reputation: 3035

I built an app based on the info you described here, and was able to reproduce your problem by having an Inquery record with nil values for product (also for text). You may wish to add better validators so that Inqueries with nils cannot be saved.

Here's a paste from my rails console session:

  Inquery Load (0.1ms)  SELECT "inqueries".* FROM "inqueries" 
#<Inquery:0x00000002c03e40>
 => [#<Inquery id: 1, text: nil, phone: nil, zip: nil, product_id: nil, state: nil, street: nil, city: nil, created_at: "2012-08-17 15:23:49", updated_at: "2012-08-17 15:23:49">] 

1.9.3p194 :002 > Inquery.all.each { |n| puts n.product.name }
  Inquery Load (0.2ms)  SELECT "inqueries".* FROM "inqueries" 
NoMethodError: undefined method `name' for nil:NilClass

As an aside, and now for some unsolicited advice: a field with the same name as a keyword, "text", is a really bad idea. You might not shoot yourself in the foot today, but you will at some point. Consider renaming the text field to usertext or description or something like that.

Upvotes: 1

Solomon
Solomon

Reputation: 7043

You have an Inquery that does not have a product attached.

When you call inquery.product you are returning a nil value, and when you then call .name on the nil value, you are getting the error. This has nothing to do with has_one or has_many

Upvotes: 2

Related Questions