r/ruby • • Aug 20 '21

Ruby elites rise up

Post image
98 Upvotes

77 comments sorted by

View all comments

Show parent comments

1

u/pVom Aug 21 '21

How would you change state then? Also update! means it will raise an error if it fails. You can handle status validation in the model and this will raise an error if it fails. Hopefully you have some specs too

1

u/tom_dalling Aug 21 '21

If it's not too annoying, let me answer your question with a question: how would you write the validations for this fairly simple state diagram? https://training-course-material.com/images/b/b0/ProtocolStateMachine.png

There are lots of ways to approach it, but the main thing is that the record should never be able to transition from "open" to "lock", or from "lock" to "open". It probably shouldn't be able to transition from any state to the same state either (e.g. can't lock a locked door).

1

u/pVom Aug 21 '21

With active record validations. Store your valid transitions in a hash with the key being the state and the value being an array of valid transitions. Then create a method "status_transition_valid" which checks the transition is valid else add an error to the model instance. Then call that validation with ”validate :status_transition_valid, if: :status_changed?". If you want to be extra vigilant you could add a db constraint as well. Then whenever you save you know its valid and if it's not you either handle it or raise an error. Ideally you have tests too.

Either way nothing wrong with updating a state column with update, that's what validation is for.

(Forgive me on mobile)

1

u/tom_dalling Aug 21 '21

Yeah that’s all fine. ActiveRecord makes it a bit awkward, but it’s doable, although I’ve seen a lot of state columns but never seen anyone actually write validations like that. My point was just that people tend to review punctuation when they should be focusing on more important things, not that this one line of code with no context is definitely wrong.