Search code examples
ruby-on-railsmethodsassociationsmodelsattr

NoMethodError at /line_items undefined method `price' for nil:NilClass, simple model attribute unrecognized


I cannot access an associated model from another model while defining a method. I get the following error when trying to access an objects attibute (size's 'price' attribute) while in an associated object (line_item). Below is my code and errors:

models

class LineItem < ActiveRecord::Base
  attr_accessible :cart_id, :product_id, :quantity, :unit_price, :product, :cart, :color_id, :size_id, :extra_id, :color, :size, :extra
  belongs_to :cart
  belongs_to :product
  has_one :color
  has_one :size
  has_one :extra
  validates :quantity, :presence => true
  def item_price
    if size.price.nil? || size.price == 0
      if  extra.price.nil? || extra.price ==0
        product.price
      else
        product.price + extra.price
      end
    else
      if extra.price.nil? || extra.price == 0
        product.price + size.price
      else
        product.price + size.price + extra.price
      end
    end
  end
  def full_price
          unit_price * quantity
  end
end


class Size < ActiveRecord::Base
        attr_accessible :name, :price, :product_id, :line_item_id
        belongs_to :product
        belongs_to :line_item
  def size_display
    "#{name} +#{price}"
  end
end

controller

class LineItemsController < ApplicationController
  def new
    @line_item = LineItem.new
  end
  def create
    @line_item = LineItem.create!(params[:line_item].merge(:cart => current_cart))
    @line_item.update_attributes!(:unit_price => @line_item.item_price)
    redirect_to current_cart_url
  end
end

error

NoMethodError at /line_items
undefined method `price' for nil:NilClass

LineItem#item_price
app/models/line_item.rb, line 10
LineItemsController#create
app/controllers/line_items_controller.rb, line 7

Any insight appreciated.

Update

My size object doesn't seem to be nil through analyzing my request parameters, what could be causing this?

Update No. 2

good debug info found from console:

1.9.3-p125 :008 > debugAttempt = LineItem.first
  LineItem Load (0.9ms)  SELECT "line_items".* FROM "line_items" LIMIT 1
 => #<LineItem id: 1, unit_price: nil, product_id: 1, cart_id: 1, color_id: 1, size_id: 2, extra_id: nil, quantity: 2, created_at: "2013-06-25 03:41:27", updated_at: "2013-06-25 03:41:27"> 
1.9.3-p125 :009 > debugAttempt.size
  Size Load (0.3ms)  SELECT "sizes".* FROM "sizes" WHERE "sizes"."line_item_id" = 1 LIMIT 1
 => nil 
1.9.3-p125 :010 > debugAttempt.size_id
 => 2 
1.9.3-p125 :015 > Size.find(debugAttempt.size_id).price.round
  Size Load (0.6ms)  SELECT "sizes".* FROM "sizes" WHERE "sizes"."id" = $1 LIMIT 1  [["id", 2]]
 => 50 

so basically size isn't nil but rather i can't find access the associated size object from the lineItem object. i can only access size_id.

Any ideas on how to solve this?


Solution

  • Since your LineItem has_one Size, foreign key should be in your sizes table. So you should rather debug with Size.find_by_line_item_id(debugAttempt.id) and if the result is nil, the associated record simply doesn't exist in db.