【问题标题】:Rails using state machine in polymorphicRails 在多态中使用状态机
【发布时间】:2020-01-06 05:34:35
【问题描述】:

我有这个多态模型。

class Note < ApplicationRecord

  belongs_to :notable, polymorphic: true, optional: false


  state_machine :is_status, initial: :pending do
    transition pending: :approved, on: %i[approve]
    transition pending: :cancelled, on: %i[cancel]
  end
end

和其他两个模型

class Invoice < ApplicationRecord

  has_many :notes, as: :notable, dependent: :destroy
end

class Person < ApplicationRecord

  has_many :notes, as: :notable, dependent: :destroy
end

如您所见,我在两个模型中附加了个人或发票的注释。并且还使用状态机。场景是我只想在invoice 中使用状态机?这可能吗。 所以。如果我的 notable_type 是“发票”。我的状态是“待定”,否则我的状态是 Person:nil

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-4 ruby-on-rails-5 state-machine


    【解决方案1】:

    我建议您创建一个封装状态机行为的新模型,然后将该模型附加到发票上。

    如果状态机旨在表示 Invoice 的状态,则将其设置为 InvoiceState belongs_to Invoice 和 Invoice has_one InvoiceState。

    另一方面,如果您想使用此状态机来表示更一般的完整性概念,则将其命名为适当的通用名称(TransactionState 等)并通过多态关系附加它,例如 Note。

    我描述的可能是这样的:

    class Note < ApplicationRecord
      belongs_to :notable, polymorphic: true, optional: false
    end
    
    class Person < ApplicationRecord    
      has_many :notes, as: :notable, dependent: :destroy
    end
    
    class Invoice < ApplicationRecord    
      has_many :notes, as: :notable, dependent: :destroy
      has_one :invoice_state, dependent: :destroy
    end
    
    class InvoiceState < ApplicationRecord
      belongs_to :invoice, optional: false
    
      state_machine :status, initial: :pending do
        transition pending: :approved, on: %i[approve]
        transition pending: :cancelled, on: %i[cancel]
      end
    end
    

    【讨论】:

    • 它对我来说看起来很干净。但意思是我将创建一个具有一列名称 is_status 的表格发票状态???
    • 除了 is_status,InvoiceState 表还需要一列作为自己的主键 (id) 和一列作为发票外键 (invoice_id)
    • 是的,我知道您的意思是参考 ID。如您所见,我尝试将其应用到我的项目中。我的例子只是我的复制品。给我时间在我的实际项目中应用它并接受你的回答。
    【解决方案2】:

    如我所见,您可以将notable_type == Invoice 传递给状态机以过滤其他 notable_types 的条件

    【讨论】:

    • 你能举个例子吗?
    【解决方案3】:

    您可以参考 AASM gem。 https://github.com/aasm/aasm .这不仅可以帮助您在所有转换中添加保护方法,还可以在回调之前和之后。

    您还可以添加 AASM 挂钩方法并在那里设置状态。例如:-

    class Note < ApplicationRecord
      belongs_to :notable, polymorphic: true, optional: false
      include AASM
      aasm do
        state :pending
        state :approved
        state :cancelled
        event :approve do
          transitions from: :pending, to: :approved, before: some_method, after: some_method1
        end
        event :cancel do
          transitions from: :pending, to: :cancelled, before: some_method2, after: some_method3
        end
      end
        def aasm_ensure_initial_state
          if notable_type == "Invoice"
            self.aasm_state = :pending
          else
            self.aasm_state = nil
          end
        end
        def some_method
            puts "Some actions can be taken here."
        end
      end
    end
    

    【讨论】:

    • 让我检查一下
    • 我应该把'some_method'放在哪里
    • 您可以将 some_method 定义放在 aasm 块之后。我正在更新上述描述并添加 some_method。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-13
    • 1970-01-01
    相关资源
    最近更新 更多