如何修复冲突迁移的提交?

时间:2016-02-15 01:58:43

标签: ruby-on-rails ruby activerecord rails-activerecord rails-migrations

假设有一个迁移创建了一些记录,并且有两个提交看起来像这样

# 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属性不会存在。有没有办法纠正这种情况?

1 个答案:

答案 0 :(得分:-1)

我会在这里做两件事:

  1. 不允许capital列中的NULL。允许NULL是Rails的默认值,但它几乎总是错误的选择,所以手动使列NOT NULL。您可能希望将此应用于表中的所有其他列:如果您无法证明列中的NULL,请将其设为NOT NULL。

  2. capital列中包含一个默认值 - 在数据库中,而不仅仅在您的Rails代码中。

  3. 这会使迁移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,则所有后续回调和相关操作都会被取消。