1

您好,我正在尝试从《Agile Web Development with Rails》一书中学习 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。谢谢你的回答。

4

2 回答 2

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 控制台从数据库中删除以前的 LineItem 记录,否则您仍然会看到此错误,因为旧 LineItems 未与 Product 关联。

于 2013-07-21T15:57:37.570 回答
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

结束`

PS不要忘记将数量默认值更改为'0'

于 2013-07-21T16:06:51.423 回答