【问题标题】:Agile Web Development with Rails - ActiveRecord::StatementInvalid Error使用 Rails 进行敏捷 Web 开发 - ActiveRecord::StatementInvalid 错误
【发布时间】:2011-11-25 02:58:28
【问题描述】:

我是 Rails 新手,我已经开始阅读“使用 Rails 进行敏捷 Web 开发:第四版”。我目前在购物车创建章节。我主要是从书中复制代码,但是我的数据库被称为“dvds”而不是“产品”(因为我正在为一个项目创建一个 DVD 商店)。

我已经到了本章的结尾,当我运行功能测试时,我收到以下错误:

test_should_destroy_dvd(DvdsControllerTest):
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: line_items.dvd_id: SELECT COUNT(*) FROM "line_items" WHERE ("line_items".dvd_id = 980190962)
app/models/dvd.rb:26:in `ensure_not_referenced_by_any_line_item'
app/controllers/dvds_controller.rb:76:in `destroy'
test/functional/dvds_controller_test.rb:50:in `test_should_destroy_dvd'
test/functional/dvds_controller_test.rb:49:in `test_should_destroy_dvd'

这是它所引用的 dvd.rb 文件中的代码:

has_many :line_items 
before_destroy :ensure_not_referenced_by_any_line_item
...
private
  def ensure_not_referenced_by_any_line_item
if line_items.empty?
  return true
else
  errors.add(:base, 'Line Items present')
  return false
 end
end

dvds_controller.rb 中的代码:

def destroy
    @dvd = Dvd.find(params[:id])
    @dvd.destroy

    respond_to do |format|
      format.html { redirect_to(dvds_url) }
      format.xml  { head :ok }
    end
  end

还有来自 dvds_controller_test.rb 的代码:

test "should destroy dvd" do
    assert_difference('Dvd.count', -1) do
      delete :destroy, :id => @dvd.to_param
    end

    assert_redirected_to dvds_path
  end

基本上,我不理解错误,我正在寻求帮助以使其消失!我猜问题出在“没有这样的列:line_items.dvd_id”,但我不知道如何修改它。我已经融化了我的大脑试图弄清楚,所以任何帮助都将不胜感激。

编辑: 这似乎是问题所在,在 create_line_items.rb 中:

class CreateLineItems < ActiveRecord::Migration
  def self.up
    create_table :line_items do |t|
      t.integer :product_id
      t.integer :cart_id

      t.timestamps
    end
  end

  def self.down
    drop_table :line_items
  end
end 

另外,这里是 scehma:

ActiveRecord::Schema.define(:version => 20111125123848) do

  create_table "carts", :force => true do |t|
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  create_table "dvds", :force => true do |t|
    t.string   "title"
    t.text     "description"
    t.string   "image_url"
    t.decimal  "price",       :precision => 8, :scale => 2
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  create_table "line_items", :force => true do |t|
    t.integer  "product_id"
    t.integer  "cart_id"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

end

【问题讨论】:

    标签: ruby-on-rails


    【解决方案1】:

    确保您运行 rake db:migrate 来创建您的数据库。

    【讨论】:

    • 我只是仔细检查了一下,我确实运行了迁移。谢谢
    【解决方案2】:

    我认为架构看起来不错,迁移缺少 dvd_id。你是如何在你的架构中得到 dvd_id 的?你有另一个添加它的迁移吗?

    可能值得检查数据库中的实际内容:

    sqlite3 db/development.sqlite3
    
    sqlite3> .schema line_items
    

    检查 line_items 确实有 dvd_id 列

    【讨论】:

    • 啊,我试过 rename_column 看看能不能解决问题。 (为了清楚起见,我已将上面的代码改回原来的形式)所以是的,你是对的,我的问题是我有一个 product_id 列而不是 dvd_id 列。我该如何解决这个问题?
    • 您需要创建另一个具有 rename_column 的迁移。然后重新运行 rake db:migrate
    【解决方案3】:

    就像 Cat 所说,确保您运行了迁移,但还要注意您可能忘记更改迁移中的列名。我的猜测是过去它是product_id。如果您还发布了与 LineItem 和当前 db/schema.rb 相关的迁移,将会很有帮助。

    【讨论】:

    • 你在钱上:product_id。我已经使用上面的迁移和架构代码编辑了我的原始帖子。我怎样才能解决这个问题?非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-30
    • 1970-01-01
    • 2012-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多