Beginner design question: Best approach to model a step-by-step order


I’m building an app for a big event location, and clients book a stay there, they can add

  • multiple guests to stay in different rooms
  • book seminars
  • book additional spa treats
  • maybe more

I partly use turbo-frames, partly new page loads. When building up these (slightly) complex orders, I may want to temporarily save them in the databse, even when unfinished. So I cannot easily use model validations.

I thought about this: I introduce a bool finished tag in the booking model, have less strict validations in the model when :false, and when the booking is complete I change that to :true, and ensure that the booking contains all data needed. Then I run once a day (or week?) a script to delete all unfinished bookings.

Is this a best practices approach or will I run into trouble and there is a better way to do it, like sessions? Can I still use the rails standard validations somehow? Like

validates :name, presence: true if :finished

so it would validate after being finished? but how does finish say it is finished without having validated what is finished? Or am I misunderstanding. Is the usecase that someone does not have to fill the form out again when coming back to it, or do you want to save state of modules for some combination logic? or something else… oh, so they are booked in and book extras that get added to their package?

The idea is that it validates more freely when the :finished tag is :false but has stricter validation when :finished is true. So you start by setting only certain fields when creating the booking step-by-step, which is allowed to save, but only after ALL fields have been set, you set :finished to :true, so only fully completed bookings are allowed to save with :finished == :true.

So you CAN save a “booking” in an incomplete state, but only if not finished. And if :finished == :true you are certain that all fields are filled in.

So when you work with all the bookings fully done, you ignore all data entries with :finished == false, and only handle the others.

I hope that clears it up.

Have a look at validation contexts. It’s mentioned in the main Rails Guide on Validation. This is well supported and I’ve used it before for what you describe.


Oh that’s perfect! Context validation and conditional validation gives me all that I need. Sorry for not finding it myself, the amount of documentation can be a bit overwhelming in the beginning. Thanks - again!

Quick suggestion: Don’t delete unfinished orders. You can later create a conversion funnel based on how much of the order was filled, and figure out which steps is causing most people to leave. In our app we have plenty of those “multi-step forms” and this technique has helped us consistently optmize them.


For situations like this I typically create a state machine using “state_machines-activerecord” and/or “state_machines” with each step of the state machine being a step in the wizard flow. Then you can have different sets of validations grouped by each wizard step. See the validation examples in the READMEs

One thing you might want to consider: It could be annoying to users to have to go back and enter information they were not required to enter at first.

A common pattern for these things is getting the minimal info from the users in order to save to db, and then asking them on their profile or booking page for the info that is needed.

And you can use this to require more info to finish a booking:

validates :something, if: :state_complete?