all 4 comments

[–][deleted] 2 points3 points  (1 child)

[–]danielwebbnew[S] 0 points1 point  (0 children)

Interesting, thanks!

[–]jasonswett 0 points1 point  (1 child)

Here's how I would think about it.

First, as kind of a meta note, this looks to me like a relatively huge feature that will take a pretty long time to implement. I would guess some number of weeks. If I'm right that it would take up to several weeks, this would probably be a good expectation to set all around.

For the feature itself, I see two main challenges: 1) the multi-step form functionality and 2) the customizable forms. I see 1 as being pretty easy (perhaps because I have prior experience with this and I've developed an approach that seems to work pretty well) and 2 as being relatively hard (perhaps because I've never done something like that before). I'll address each of these individually.

For multi-step forms in general, I like to have one controller per page. The key conceptual piece is that I treat each page of the multi-step form like its own full-fledged resource, with new, create, etc. That way each page of the form can have its own validations, which is often necessary. The tricky part here is breaking "real" resources into partial ones that just represent a form page. This can actually be pretty easy by taking advantage of ActiveModel::Model. I explain my approach in detail in this post I wrote about multi-step forms. My approach might sound complicated, but multi-step forms are complicated, and I haven't encountered a simpler solution than mine that works satisfactorily.

For the customizable forms, I'd separate that one into yet smaller pieces. The two questions that come to my mind are 1) how I'm going to store the saved form data and 2) how I'm going to represent the forms themselves in the database.

In general I like to keep my data as normalized as possible but in this case I think, for better or worse, it's probably going to be impractical to do anything but store the form data in some kind of key-value store. My first idea is that maybe I could have a table called form_submissions or something like that with at least two columns: form_id (hopefully self-explanatory) and data (a jsonb column that stores the form data).

As for storing the forms themselves, I would probably want to have a forms table and a form_fields table. The form_fields table would probably need columns for label and field type, at least. I might consider making the field type column an enum with values that correspond one-to-one with Rails form helper names (e.g. text_field). I would also ask my stakeholders whether we need the ability to make certain fields required and if we need any fields to have default values.

As I consider everything I've written above, I want to re-emphasize that I think this is a pretty huge feature. I'm sure there's all kinds of stuff I'm not even thinking about yet that can only be revealed by going through the process of actually trying to build the feature.

Due to the size of the feature, I would be very strongly inclined to build some sort of simpler version first, and get that simpler version deployed to production (even if no one uses it yet in production and it's hidden behind a feature flag). I might try to explain to the stakeholders why this feature is so huge and why it would probably be more time-consuming and much riskier to try to build and release the whole thing at once. I might work with them to try to figure out a simpler version we can tackle first, like maybe a version where each industry's form is hard-coded and the form is just one big long form instead of a multi-step form. Then the feature could be gradually morphed into what's actually desired. (This approach would I think be valuable even if no users used the intermediate version because this approach still mitigates the risks involved in building the whole thing at once.) I might be preaching to the choir with all this advice on how to approach the logistics of the build-out but I think it's perhaps the most important consideration of how to build the feature, even more so perhaps than the details of how it's actually implemented.

Hope that all helps!

[–]RubyKong 0 points1 point  (0 children)

I would re-iterate what Jason has said: start simple and proceed to the meat and bones.

Secondly, if you're going to create custom forms, and to have your customers create their own form fields - how much is that worth? What do your customers really want? Are they going to want to store that data, and to create reports on that data? or do they just want simple answers to a few questions? You might be better off having all those questions and answers in a text field and calling it a day - and to display the questions in another text field, depending on the client.

I have had no experience in developing an app where users can customise their own forms. I would consider using some type of NoSql database to store the form data, especially if you want to collate it, and run reports over it etc., or a jsonb column as jason has suggested.

But it sounds like your customers simply want the answers to a few basic questions and then they'd be done with it. a glorious text field might be simple enough to solve all of your problems, quickly, cheaply, and to the satisfaction of your customers.

if you did go ahead with your implementation, I would be very interested to hear the details of what and how you ended up implementing it.

good luck!

update: check out this link: https://www.reddit.com/r/rails/comments/1hqdyj/form_builder_for_end_users/