I am wondering if there's a way to make the state event private when using the state_machine gem?
I have a three states
unpaid, pending, paid.
When a receipt is in unpaid then an event can be fired to charge the user. This switches the receipt to pending (while it talks to the merchant service) Then once it is done, it would call the pay event and thus set the state to paid.
The user of the receipt class can technically call the pay event, which would switch the receipt to paid even though it didn't run through the merchant.
NOTE: THIS IS A CONTRIVED EXAMPLE...
I am a strong believer in private and protected methods, and I was wondering how one would engage them in the context of a state_machine implementation..
I'm assuming you're talking about this state_machine.
You can easily make your event transition methods private by marking them as so after their definition, e.g.
class Payment
attr_reader :state
state_machine :state, :initial => :pending do
event :pay do
transition [:pending] => :paid
end
end
private :pay # that should do!
end
Even though it answers your question, I highly advise against it. Making a method private or protected, only concerns about method visibility, i.e. what you want to expose in your API. What you should really be looking for in your case, is a way to control access to a certain feature in a certain moment. This requirement is highly coupled with your domain logic, and not API.
Besides, even if you mark your methods as private, it does not guarantee any security because one can easily bypass this restriction calling the method via send, e.g payment.send(:pay)
.
I think a better solution would be to create some sort of policy checker or filter before your transactions to make sure they can be processed, e.g.
before_transition :pending => :paid, :do => :check_merchant
def check_merchant
really_paid = ... # logic to check with the merchant
or raise "Payment haven't been processed yet. Hang on a sec"
end
Hope that helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With