我只能通过慢慢地完成迁移来解决这个问题。在过去的两天里,我一直在尝试做一些简单的事情。从我的verdict:text
表格中删除一列simulations
,然后添加另一列:opinions:hash
。
这样做会导致各种错误,例如没有方法'my_sym',并且说模拟表不存在。
我最初认为我通过这样做解决了这个问题:
rake db:drop
rake db:schema:dump
rake db:migrate VERSION="<Migration1>"
rake db:migrate VERSION="<Migration2>"
rake db:setup ENV="test"
迁移1:
class DeviseCreateUsers < ActiveRecord::Migration
def change
create_table(:users) do |t|
## Database authenticatable
t.string :email, :null => false, :default => "", limit: 96
t.string :encrypted_password, :null => false, :default => "", limit: 60
t.timestamps
t.index :email, unique: true
end
end
end
迁移2:
class CreateSimulations < ActiveRecord::Migration
def change
# Needs the hash column worked out before this is run
create_table :simulations do |t|
t.integer :x_size
t.integer :y_size
t.string :verdict
t.string :arrangement
end
add_reference :simulations, :user, index: true
end
end
这让我回到了原点(我的所有测试工作似乎都处于我开始遇到问题之前的初始状态),所以我重新编写了两个令人不快的迁移,认为它们可能是问题,运行了两个按此顺序迁移(我删除了列,然后添加了另一个,与我之前尝试的相反的顺序,想到可能订单有一些效果)。
迁移3:
class RemoveVerdictFromSimulation < ActiveRecord::Migration
def change
remove_column :simulations, :verdict, :string
end
end
迁移4:
class AddOpinionToSimulations < ActiveRecord::Migration
def change
add_column :simulations, :opinion, :hash
end
end
编辑:经过进一步调查,第4次迁移导致了模拟表无故障的问题。
这些迁移均可正常运行。但是我知道做其他事情会导致错误(例如运行rspec),因为看起来问题是这些迁移之一会导致schema.rb
文件出错。
运行这些最后一次迁移3&amp; 4后,我之前同时拥有用户和模拟表的schema.rb
如下所示:
ActiveRecord::Schema.define(version: 20150807193122) do
# Could not dump table "simulations" because of following NoMethodError
# undefined method `[]' for nil:NilClass
create_table "users", force: :cascade do |t|
t.string "email", limit: 96, default: "", null: false
t.string "encrypted_password", limit: 60, default: "", null: false
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "users", ["email"], name: "index_users_on_email", unique: true
end
这里特别感兴趣的是:
# Could not dump table "simulations" because of following NoMethodError
# undefined method `[]' for nil:NilClass
任何人都可以了解这里发生的事情或我如何解决这个问题?我已经坚持了几个小时。
有一件事值得注意,当我重新运行rake db:schema:dump
时,由于某些原因,我需要注释掉我的工厂,因为它们似乎会导致模拟表存在错误。不确定为什么他们被调用只是认为这个信息可能会有所帮助,这里他们都是:
FactoryGirl.define do
factory :simulation do |f|
f.id (Simulation.last.nil? ? 1 : Simulation.last.id + 1)
f.x_size 3
f.y_size 3
f.user_id 1
end
end
-
FactoryGirl.define do
factory :user do
email "user_#{User.last.nil? ? 1 : User.last.id + 1}@home.com"
password "password"
end
end
答案 0 :(得分:1)
我认为问题就在这里:
class AddOpinionToSimulations < ActiveRecord::Migration
def change
add_column :simulations, :opinion, :hash
end
end
没有hash
列类型。遗憾的是,SQLite将允许您创建任何类型的列(将无法识别的内容视为字符串),但ActiveRecord不知道如何处理它们。结果是您的迁移工作正常,但架构转储失败,因为ActiveRecord不能说:
t.hash :opinion
在schema.rb
文件中。
如果您真的认为要在列中存储哈希值,则需要创建text
列:
add_column :simulations, :opinion, :text
然后在模型中使用serialize
:
serialize :opinion, Hash
当然,在您的数据库中留下了一个不透明的YAML blob,您无法(明智地)查询,因此只有在您可以使用它时才能使用它。
更好的解决方案是规范化opinion
哈希值,以便将信息存储在单独的表格/模型中。