Form Objects Design Pattern Discussion
Nice episode, I've been using forms like this all over the place, especially when an AR object can be saved via many different use cases with many different "valid" states. One quibble, seem more clear to do something like:
if @contact_form.valid?
ContactMailer.message(params).deliver_later
redirect_to ...
end
especially since the contact form is not really saving anything.
as far as ideas for further examples: in the realm of interesting forms I'd be curious to see your approach to a multi-step, "Wizard"-style experience where multiple forms are filled out for different records (with or without branching paths depending on earlier data :) )
Yep definitely relevant, the old wizard where you need to progressively build up multiple associated models across a few steps.
I know this can be done "big-bang" style using Javascript, but then risks the user losing some of the data if it isn't written back/progressively validated at each logical step.
An example for the work we do, in our case, we deal with the provision of a lot of information based products, which require the user to enter a lot of their information in, and then they finally submit the "form" at the end, but it might have been 5 - 6 steps/pages updating/creating multiple models.
Currently, we've used Wicked Wizard gem to hide a lot of the mess away from non-RESTfully updating a model (or multiple).
Would be great to get some more insights as to how a Form Object could be applied in the context of a wizard. Currently, we're using a liberal application of nested_attributes_for, but it's quite brittle, and particularly, requires a lot of condition validation for each step that saves back to the model (because they are all pretty much only ever partially valid at each step until the final step is saved)..
An example: say our primary model is an CarInsuranceQuote, and associated to this CarInsuranceQuote model would Addresses, Names, Cars.
Form Step 1: Car Details & Name of Insured (creates a new CarInsuranceQuote, and build associated Name model on the quote, eg CarInsuranceQuote.cars.new(car_attrs), CarInsuranceQuote.names.create(names_attrs).
Form Step 2: Address Details for Quote,
ie: CarInsuranceQuote.addresses.create(address_attrs). And maybe save a few other attributes on the CarInsuranceQuote.update_attributes(ciq_attrs).
Form Step 3: Finalise Quote by Creating a User for the quote
ie: CarInsuranceQuote.users.create(user_attrs).
As you can see, each step would build different associations, but might also partially update the parent model in the Wizard.
Awesome episode! Building something like this in an existing project as we speak (or as I type) :)
Hey, Chris!) 10Q for awesome episode=) What do you think about "Interactor Pattern"? It could be very interesting and useful for community to build it from scratch and use 'interactor' gem for organizers!) Something like this:
https://mkdev.me/en/posts/a...
Thank You for attention)
Piece=)
Do we really still need strong parameters after implementing a form object ? Because the form object only has the fields that are relevant for the form and i don't see any way in injecting data back to the original object.
Your comment emphasizes the use of Form Objects Design Pattern in various applications. He highlights a preference for checking validity using "@contact_form.valid?" before sending mail. This ensures that the contact form's state is appropriate, even though it doesn't save anything. This approach enhances code clarity and allows for different "valid" states, adhering to a more versatile design pattern. It's a good example of leveraging design patterns for more maintainable and understandable code.