Рельсы с использованием конечного автомата в полиморфном - PullRequest
1 голос
/ 06 января 2020

У меня есть эта полиморфная c модель.

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 это "Счет-фактура". Я получил свой статус "в ожидании", в противном случае если я получил статус: ноль

Ответы [ 3 ]

1 голос
/ 06 января 2020

Вы можете обратиться к драгоценному камню AASM. 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
1 голос
/ 06 января 2020

Я рекомендую вам создать новую модель, которая инкапсулирует поведение конечного автомата, а затем присоединить эту модель к накладной.

Если конечный автомат предназначен для представления состояния накладной, сделайте так InvoiceState belongs_to Invoice и Invoice has_one InvoiceState.

С другой стороны, если вы хотите использовать этот конечный автомат для представления более общей концепции полноты, тогда назовите его соответствующим образом generi c (TransactionState , et c.) и присоедините его через отношения полиморф c, как Примечание.

То, что я описываю, может выглядеть так:

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
1 голос
/ 06 января 2020

Как я вижу, вы можете передать notable_type == Invoice условие конечному автомату для фильтрации других notable_types

...