假设有一个迁移创建了一些记录,并且有两个提交看起来像这样
# commit 1 by Alice
# migration
def up
create_table :cities do |t|
t.string :name
end
City.create!(name: 'New York')
City.create!(name: 'Moscow')
end
# commit 2 by Bob
# migration
def change
change_table :cities do |t|
t.boolean :capital
end
end
# model
class City
before_create :set_capital
def set_capital
capital = false
end
end
现在,如果第三人拉动代码迁移将失败,因为capital
属性不会存在。有没有办法纠正这种情况?
答案 0 :(得分:-1)
我会在这里做两件事:
不允许capital
列中的NULL。允许NULL是Rails的默认值,但它几乎总是错误的选择,所以手动使列NOT NULL。您可能希望将此应用于表中的所有其他列:如果您无法证明列中的NULL,请将其设为NOT NULL。
在capital
列中包含一个默认值 - 在数据库中,而不仅仅在您的Rails代码中。
这会使迁移2看起来像:
change_table :cities do |t|
t.boolean :capital, :null => false, :default => false
end
如果您同时执行这两项操作,那么数据库将在添加新列时填写默认值,您的问题就会消失。
我倾向于将数据库视为一个完全独立的应用程序,其接口恰好是SQL(大部分)隐藏在ActiveRecord或其他ORM之后。
我也同意评论者在迁移中使用模型是一个坏主意。
顺便说一句,你的set_capital
方法没有做你认为的做法。你想说:
def set_capital
self.capital = false
true
end
capital = false
仅创建一个局部变量,然后set_capital
将返回false
;因此,set_capital
无法初始化capital
属性和before_*
callback return false
will stop everything in its tracks:
取消回调
如果
before_*
回调返回false
,则所有后续回调和相关操作都会被取消。