I always use accepts_nested_attributes_for in Rails and @rbates approach always worked well for me. I even tried to use some gems, cocoon and nested_form_fields, inspired by this method, but the way they were conceived didn't fit well for me. I will not explain why, first because I already forgot :), second because I'm not interested in trying to generalize the idea.
In my day-to-day work I use @rbates approach, the ActiveType gem, and some jQuery to add/remove fields, but from now on I will add vue.js to my toolbox! This I can explain why, and I’m writing this because I think that you could like it too.
First, what is my problem? Simple, I have a table with two dimensions: categories x deadlines. To make it simple, go see it working:
If you take a look at the HTML/CoffeScript it’s fairly standard nested fom. The CoffeeScript logic is to add new lines/columns and update the inputs with right indexes for categories_attributes, listener_deadlines_attributes and listener_deadline_values_attributes. Not that complicated, isn’t is? Err… I’m not sure about this… :)
The ugly comes now. This table contains deadlines for listeners, but I also need deadlines for presenters, but categories are common for both. Yeah, it’s a kind of conference system, I’m glad you asked! ;)
I though about some options, always adding a second table:
- Extract the fields from the table, edit them elsewhere, and use only labels for both tables;
- Only allow to add/delete lines from one table, making the other one read-only, facilitating the sync task;
- Allow add/delete from both tables, and also allow the user to change the input content, keeping both in sync;
- Redesign all the interface as a wizard (a friend sugestion given after I started implementing 3, and discarded due laziness)
The option 3 is the one that pleased me more and I believed that it’s implementation, with jQuery, would be easy, but once I started drawing an approach in my mind, I began to believe that my code would tend to get even worse :/
So, I decided to take a second look in vue.js. The first time I looked at it I though: “This looks like backbone.js, why would anyone use this instead of backbone?”. For my surprise, in this second look, I was enlightened: “This is much simpler than backbone, let's give it a try!”
There is already some people using vue.js as an alternative to Rails nested forms, the most popular appear to be the post written by Ryan McMahon, but I want exactly the opposite: give super powers to nested forms, aka dynamic behaviour :)
Why I like nested forms so much? They allow a really simple interaction with the server and I can benefit from ActiveRecord validations. Using other approach means write code to send request, verify if there is any error, do this, do that, blah blah blah… I just want to render the same page with the errors outputted by the form helpers. I find this interaction so simple, and so powerful, that I want to keep it. I just want to add some dynamic behaviour!
Okay, talk is cheap, show me the code:
I just find the final result wonderful! It's incredible more simple and more focused. Vue.js allowed me to concentrate much more in the interaction between user and data.