gocardless / statesman

A statesmanlike state machine library.
https://gocardless.com/blog/statesman/
MIT License
1.79k stars 163 forks source link

Sorbet compatible queries #498

Closed stephenbinns closed 1 year ago

stephenbinns commented 1 year ago

Including ActiveRecordQueries to your model can cause issues with type checkers such as Sorbet, this is because this technically is using a dynamic include, which is not supported by Sorbet.

e.g.

class Order < ActiveRecord::Base
  has_many :order_transitions, autosave: false
  include Statesman::Adapters::ActiveRecordQueries[transition_class: OrderTransition, initial_state: :pending]

  def state_machine
    @state_machine ||= OrderStateMachine.new(self, transition_class: OrderTransition)
  end
end

Cannot be parsed by Sorbet - https://sorbet.org/docs/adopting#step-4-fix-constant-resolution-errors

Sorbet cannot statically analyze a codebase that dynamically includes code. For example, code like this is impossible to statically analyze. Dynamic includes must be rewritten so that all includes are constant literals.

To avoid these issues you can instead include the TypeSafeActiveRecordQueries module and pass in configuration, for example:


class Order < ActiveRecord::Base
  has_many :order_transitions, autosave: false
  include Statesman::Adapters::TypeSafeActiveRecordQueries
  configure_state_machine transition_class: OrderTransition,
                          initial_state: :pending
  def state_machine
    @state_machine ||= OrderStateMachine.new(self, transition_class: OrderTransition)
  end
end