How do you decouple your application’s forms from your models/ schemas?
Background: So far my forms have just been 1–1 interfaces for my schemas. I mostly just continued the pattern which the Phoenix generators suggest and it worked fine. However, I’ve now run into a situation where this approach doesn’t really work and I feel like there should be another layer between contexts and controllers.
In my schema
clients I have a
client_number field. Now in my form I want to have a checkbox
autogenerate_client_number? which determines if a client number should be generated on saving or the user input should be used. Using the generator’s approach I quickly added the
autogenerate_client_number? virtual field to my schema and had everything working in no time. But as it’s just for one single form, it doesn’t really belong to my
client model, so this feels wrong. Also, what if I need more settings in the future?
I thought about creating modules like
AppWeb.Forms.NewClientForm that would be embedded schemas and be used in the controller. If valid, I could then pass the data to my context functions. This works, but the issue I see is that it leads to a lot of duplication. And how would I handle changeset errors that come from my model’s schema from the context function?
I’m now using a middle way by having modules like
AppWeb.Forms.NewClientForm which them embed my model’s schema. This way I can add additional fields next to it and still get the errors from my real changeset, which is especially important for constraints. The negative part is that it leads to a lot of “manual” dealing with changesets and bloated controllers like in pre-context Phoenix apps.
One alternative I haven’t tried yet is building a small
Form module that generates changesets on the fly.
So how do you decouple your forms from your schemas? I have searched the web and forums but couldn’t find much about this (just one post actually). Thanks a lot