With state_machine stone, is there a way to make events private / protected?

I am wondering if there is a way to make the state event private by using the state_machine gem?

I have three states

unpaid, pending, paid.

When the receipt is unpaid, an event may be fired to charge the user. This switches the receipt on hold (while she speaks with the seller) Then, as soon as this is done, it will trigger a payment event and thus set the status for payment.

The user of the receipt class can technically trigger a payment event that would switch the receipt to payment, even if it was not triggered through the merchant.

NOTE: THIS IS A SPECIFIC EXAMPLE ...

I strongly believe in private and protected methods, and I was wondering how they can be used in the context of state_machine implementation.

+5
source share
1 answer

I assume you are talking about this state_machine .

You can easily make your methods of transitioning to events private by marking them as such after defining them, for example

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 

Despite the fact that he answers your question, I highly advise against him. Providing a method with a private or secure one only affects the visibility of the method, that is, what you want to open in your API. What you really have to look for in your case is a way to control access to a specific function at a particular moment. This requirement is closely related to your domain logic, not to the API.

In addition, even if you mark your methods as private, this does not guarantee any security, because you can easily circumvent this limitation by calling the method via send, for example payment.send(:pay) .

I think the best solution would be to create some kind of policy check mechanism or filter before transactions to make sure that they can be processed, for example.

 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 this helps!

+6
source

Source: https://habr.com/ru/post/1200561/


All Articles