nil的未定义方法`title':使用Rails的NilClass敏捷Web开发

时间:2013-07-21 15:36:27

标签: ruby-on-rails ruby undefined agile ruby-on-rails-4

您好我正在尝试使用Rails的Agile Web Development一书学习RoR,我收到此错误:

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'

这是产品型号:

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

购物车型号:

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

我正在使用Ruby 2.0.0p247和Rails 4。 谢谢你的回答。

2 个答案:

答案 0 :(得分:2)

可能是因为购物车商品型号未保存product_id。

1)首先,向LineItem模型添加验证。它不会解决问题,但您确定该问题与product_id有关。

validates :product_id, presence: true

2a)更新控制器以使用Rails 4强参数: http://edgeapi.rubyonrails.org/classes/ActionController/StrongParameters.html

2b)或者在学习Ruby On Rails时使用Rails 3.

更新。

您还应该使用rails控制台从DB中删除以前的LineItem记录,否则您仍会看到此错误,因为旧的LineItems与Product没有关联。

答案 1 :(得分:0)

@gvalmon是对的,但我建议尝试使用

validates :product, presence: true

我会将add_product的代码更改为至少

`   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

端 `

P.S。别忘了将qty默认值更改为'0'