【发布时间】:2016-06-29 13:48:56
【问题描述】:
我正在使用 Gem 在我的 ActiveRecords 中使用 Ruby 工作流:Workflow
现有运行代码包含:
- 我有一个 ActiveRecord: X
- 我已经进行了两次迁移:
- (Ref1) CreateX 迁移(创建表 X)
- (Ref2) CreateInitialEntryInX 迁移(在表 X 中创建一个条目)
新变化:
- 现在我想在 ActiveRecord X 中添加工作流,因此我做了:
- (Ref3) 我在 ActiveRecord Model X 中添加了工作流代码(提到 :status 作为我的工作流字段)
- (Ref4) AddStatusFieldToX 迁移(在表 X 中添加 :status 字段)
现在,当我在更改后运行 rake db:migrate 时,(Ref2) 会中断 cos Migration 会查找 :status 字段,因为它在工作流部分的 ActiveRecord 模型中提到,但是 :status 字段尚未添加,因为迁移(Ref4)尚未执行。
因此,当所有迁移按顺序运行时,所有构建都会失败,有什么解决方案吗? 我不想重新排序任何迁移或编辑任何旧的现有迁移。
我的模型看起来像:
class BaseModel < ActiveRecord::Base
#
# Workflow to define states of Role
#
# Initial State => Active
#
# # State Diagram::
# Active --soft_delete--> Deleted
# Deleted
#
# * activate, soft_delete are the event which triggers the state transition
#
include Workflow
workflow_column :status
workflow do
state :active, X_MODEL_STATES::ACTIVE do
event :soft_delete, transitions_to: :deleted
end
state :deleted, X_MODEL_STATES::DELETED
on_transition do |from, to, event, *event_args|
self.update_attribute(:status, to)
end
end
def trigger_event(event)
begin
case event.to_i
when X_MODEL_EVENTS::ACTIVATE
self.activate!
when X_MODEL_EVENTS::SOFT_DELETE
self.soft_delete!
end
rescue ....
end
end
class X_MODEL_STATES
ACTIVE = 1
DELETED = 2
end
class X_MODEL_EVENTS
ACTIVATE = 1
SOFT_DELETE = 2
end
# Migrations(posting Up functions only - in correct sequence)
#--------------------------------------------------
#1st: Migration - This is already existing migration
CreateX < ActiveRecord::Migration
def up
create_table :xs do |t|
t.string :name
t.timestamps null: false
end
end
end
#2nd: Migration - This is already existing migration
CreateInitialX < ActiveRecord::Migration
def up
X.create({:name => 'Kartik'})
end
end
#3rd: Migration - This is a new migration
AddStatusToX < ActiveRecord::Migration
def up
add_column :xs, :status, :integer
x.all.each do |x_instance|
x.status = X_MODEL_STATES::ACTIVE
x.save!
end
end
end
因此,当 Migration#2 运行时,它会尝试查找要写入的 :status 字段的初始值为 X_MODEL_STATES::ACTIVE,正如 Active Record 模型文件工作流中提到的那样:workflow_column :status并没有找到该字段,因为 Migration#3 尚未执行。
【问题讨论】:
-
请发布一些代码和实际的异常,另外,没有按正确顺序进行迁移的原因是什么?
-
@onionfeelings ,因为早期的迁移,即 Ref1 和 Ref2 已经投入生产并运行了好几个月。这是一个迁移,由于增加了要求,现在正在进行。这个问题不会出现在生产中,因为只会运行新的迁移。但是,如果有人分叉代码并在开发环境中运行,迁移会中断(我想避免)
-
你能发布你的代码吗?理论上如果你这样做: add_column :table_x, :status_id, :integer 你不应该有任何问题,而且由于你遵循约定,rails 仍然会正确处理关联
-
@onionfeelings,我已经发布了这里使用的代码供您参考。
-
@onionfeelings 我已经发布了解决方案。谢谢
标签: ruby-on-rails ruby activerecord workflow rails-migrations