Question

Hello I'm trying to learn RoR from the book Agile Web Development with Rails and I get this error:

undefined method `title' for nil:NilClass

    <ul>
        <% @cart.line_items.each do |item| %>
          <li><%= item.quantity %> &times; <%= item.product.title %></li>
        <% end %>
      </ul>
    app/views/carts/show.html.erb:4:in `block in _app_views_carts_show_html_erb___3275084074491266306_70111742218200'
    app/views/carts/show.html.erb:3:in `_app_views_carts_show_html_erb___3275084074491266306_70111742218200'

Here is Product model:

class Product < ActiveRecord::Base
    default_scope :order => 'title'
    has_many :line_items
    before_destroy :ensure_not_referenced_by_any_line_item
    validates :title, :description, :image_url, :presence => true
    validates :title, :uniqueness => true
    validates :price, :numericality => {:greater_than_or_equal_to => 0.01}
    validates :image_url, :format => {:with => %r{\.(gif|jpg|png)}i,:message => 'musí jít o adresu URL pro obrázek typu GIF, JPG, nebo PNG.'
    }
    private
    def ensure_not_referenced_by_any_line_item
      if line_items.empty?
        return true
      else
        errors.add(:base, 'Existují položky')
        return false
      end
    end
end

line_items_controller:

 def create
    @cart = current_cart
        product = Product.find(params[:product_id])
        @line_item = @cart.add_product(product.id)

    respond_to do |format|
      if @line_item.save
        format.html { redirect_to @line_item.cart, notice: 'Line item was successfully created.' }
        format.json { render action: 'show', status: :created, location: @line_item }
      else
        format.html { render action: 'new' }
        format.json { render json: @line_item.errors, status: :unprocessable_entity }
      end
    end
  end

cart model:

class Cart < ActiveRecord::Base
  has_many :line_items, :dependent => :destroy

  def add_product(product_id)
    current_item = line_items.find_by_product_id(product_id)
    if current_item
      current_item.quantity = current_item.quantity.to_i + 1
    else
     current_item = line_items.build(:product_id => product_id)
    end
    current_item
  end
end

I'm using Ruby 2.0.0p247 and Rails 4. Thank you for your answers.

Was it helpful?

Solution

It may happen because cart item model do not save product_id.

1) First, add validation to LineItem model. It will not solve issue, but you will be sure that issue is related with product_id.

validates :product_id, presence: true

2a) Update controller to play with Rails 4 strong parameters: http://edgeapi.rubyonrails.org/classes/ActionController/StrongParameters.html

2b) Or use Rails 3 while learning Ruby On Rails.

UPDATE.

You should also remove previous LineItem records from DB using rails console, otherwise you will still see this error, because old LineItems not associated with Product.

OTHER TIPS

@gvalmon is right, but I would recommend to try using

validates :product, presence: true

And I'd change your code of add_product at least to this

` def add_product(product_id, qty = 1)

current_item = line_items.where(product_id: product_id).find_or_initialize
current_item.quantity += qty
current_item.save
current_item

end `

P.S. dont forget to change qty default value to '0'

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top