繁体   English   中英

Rails 在多态中使用状态机

[英]Rails using state machine in polymorphic

我有这个多态模型。

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 是“发票”。 我得到我的状态是“待定”,否则如果是我得到状态的人:nil

如我所见,您可以将notable_type == Invoice is a condition 传递给状态机以过滤其他 notable_types

您可以参考 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

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

如果状态机旨在表示发票的状态,则使其成为 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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM