迁移期间的Ruby工作流程问题 [英] Ruby Workflow Issue During Migration
问题描述
我正在使用Gem在ActiveRecords中使用Ruby Workflow:工作流程
I am using Ruby Workflow in my ActiveRecords using Gem: Workflow
现有运行代码包含:
- 我有一个ActiveRecord:X
- 我已经有两个迁移:
- (Ref1) CreateX迁移(用于创建表) X)
- (Ref2) CreateInitialEntryInX迁移(在表X中创建一个条目)
- I am having an ActiveRecord: X
- I am having two Migrations already:
- (Ref1) CreateX migration (which creates table X)
- (Ref2) CreateInitialEntryInX migration (which creates one entry in table X)
新更改:
- 现在我想在ActiveRecord X中添加工作流程,因此我做了:
- (Ref3),我在ActiveRecord中添加了工作流程代码模型X(提及:状态作为我的工作流字段)
- (Ref4) AddStatusFieldToX迁移(在表X中添加了:状态字段)
- Now I wanted to add workflow in ActiveRecord X, hence I did:
- (Ref3) I added the workflow code in ActiveRecord Model X (mentioning :status as my workflow field)
- (Ref4) AddStatusFieldToX migration (which adds :status field in table X)
现在,当我运行rake db:migrate之后进行更改后,(Ref2)中断了cos迁移过程,它会在工作流程部分的ActiveRecord模型中提到该字段::status字段,但尚未添加:status字段作为迁移(Ref4 尚未执行。
Now when I run rake db:migrate after the changes, the (Ref2) breaks cos Migration looks for :status field as it is mentioned in ActiveRecord Model in the Workflow section, but :status field has not been added yet as migration (Ref4) has not executed yet.
因此,当按顺序运行所有迁移时,所有构建都会失败,对此有什么解决方案?
我不想对任何迁移进行重新排序或编辑任何现有的旧迁移。Hence, all the builds fail when all migrations are run in sequence, Any solution to this? I do not want to resequence any of the migration or edit any old existing migrations.
我的模型看起来像:
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
因此,当迁移#2 运行后,它会尝试查找要写入的:status字段,其初始值为
X_MODEL_STATES :: ACTIVE
,这在Active Record模型文件工作流程中已提到如:workflow_column:status
且未找到该字段,因为 Migration#3 尚未执行。So, when Migration#2 runs, it tries to find :status field to write is with initial value of
X_MODEL_STATES::ACTIVE
as it is mentioned in Active Record Model files workflow as:workflow_column :status
and does not find the field as Migration#3 is yet to execute.推荐答案
感谢所有
我找到了解决方案,并将其发布在这里。这里要发出的问题是:THANKS ALL I found the solution to this, and i am posting it here. The problems to issue here were:
- 将
:status
字段添加到ActiveRecord模型X
,而不必注释掉工作流代码,也不允许工作流在迁移期间禁止在表X
中创建实例。 - 其次,向其添加@ 007sumit指定的if条件。
- 第三,能够使用更新后的column_information <$ c重新加载模型。 $ c> Model X
- Add
:status
field toActiveRecord Model X
without commenting out Workflow Code and not let Workflow disallow creation of an instance inTable X
during migration. - Secondly, add an if condition to it as specified by @007sumit.
- Thirdly, to be able to reload Model in migration with the updated column_information of
Model X
在此处编写整个代码解决方案:
Writing whole code solution here:
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 # # if condition to add workflow only if :status field is added if self.attribute_names.include?('status') 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 end end def trigger_event(event) ... end end class X_MODEL_STATES ... end class X_MODEL_EVENTS ... 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 to add status field and # modify status value in existing entries in X Model AddStatusToX < ActiveRecord::Migration def up add_column :xs, :status, :integer # This resets Model Class before executing this migration and # Workflow is identified from the if condition specified which was # being skipped previously without this line as Model Class is # loaded only once before all migrations run. # Thanks to post: http://stackoverflow.com/questions/200813/how-do-i-force-activerecord-to-reload-a-class x.reset_column_information x.all.each do |x_instance| x.status = X_MODEL_STATES::ACTIVE x.save! end end end
@ stan-brajewski现在,此代码可以在一个部署中进行。
谢谢大家的投入:)@stan-brajewski Now, this code can go in one deployment. Thanks all for inputs :)
这篇关于迁移期间的Ruby工作流程问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!