rails 开发之路 记错本一
今天在学习《应用rails进行敏捷web开发》,跟着书上depot的例子写代码过程中遇到了一个错误。因为刚刚接触rails,所以不太明白到底是哪里出了错误。于是,我果断将问题贴在了Ruby China得到了Ruby China第一位会员也就是管理员的指导。。。非常感激。。。在这里贴出解决方案。当然了,如果有看过这本书的看客估计能够看懂我写的是什么。
问题情景:往购物车里面添加商品,如果购物车不存在则创建一个购物车,如果已经存在则将商品直接加入购物车中。若买同样的商品多个,利用quantity计数。结果却是如果购物车中已经存在这个商品了,再点击加入购物车就会报如下错误:
NoMethodError in LineItemsController#create undefined method `+' for nil:NilClass
cart的model代码如下:
#在购物车中添加商品 def add_product(product) #在line_item中根据product.id查找到对应的product current_item = line_items.find_by_product_id(product.id) if current_item current_item.quantity += 1 else current_item = line_items.build current_item.product = product end current_item end
line_items_controller中的create方法
def create @cart = current_cart product = Product.find(params[:product_id]) @line_item = @cart.add_product(product) respond_to do |format| if @line_item.save format.html {redirect_to(@line_item.cart, :notice => 'Line item was successfully created') } format.xml {render :xml => @line_item, :status => :created, :location => @line_item} else format.html { render :action => 'new'} format.xml {render :xml =>@line_item.errors, :status => :unprocessable_entity} end end end
修改line_items表的结构添加一个quantity字段,使用迁移来修改数据库。
rails g migration add_quantity_to_line_items quantity:integer
之后修改了在db目录下对应的文件
class AddQuantityToLineItems < ActiveRecord::Migration def self.up #默认是1 add_column :line_items, :quantity, :integer, :default => 1 end def self.down remove_column :line_items, :quantity end def change add_column :line_items, :quantity, :integer end end
执行迁移应用到数据库的命令///
问题就出现在执行迁移应用到数据库的过程中,在AddQuantityToLineItems类中,出现了change方法跟self.up、self.down方法的冲突。change方法是self.up跟self.down方法之和,这样就会覆盖quantity默认值为1的设置,于是出现quantity没有初始化的情况于是报了上面的错误。
解决方案可能很简单,那把change方法删掉吧。。。如果你是一个rails新手(跟我一样)可能会天真的这么认为。其实不然,这时候已经出现了脏数据。虽然已经删掉了 change,但是数据库结构已经被写进去了,开发环境下修正这个错误,可以用
rake db:migrate:redo STEP=1
重跑最后一次 migrate 任务。不过这样会丢失数据,生产环境不能这样做,只有新增 migrate 修正了。
还可进入控制台操作
rails c
> LineItem.where(:quantity => nil).update_all(:quantity => 1)
当前数据库状况可以打开 db/schema.rb 查看。