迁移期间的Ruby工作流程问题 [英] Ruby Workflow Issue During Migration

查看:75
本文介绍了迁移期间的Ruby工作流程问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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 to ActiveRecord Model X without commenting out Workflow Code and not let Workflow disallow creation of an instance in Table 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆