#196 Nested Model Form (revised)
Handling multiple models in a single form is easy with accepts_nested_attributes_for. Here you will also learn how to add and remove nested records through JavaScript.
- Download:
- source code
- mp4
- m4v
- webm
- ogv
This was one of the first casts that got me into Railscasts so I'm glad to see an update.
Just a word of caution to new users of this technique: when you have a hammer everything can look like a nail. Dynamic nested forms like this are extremely powerful and can sometimes grant the user too many chances to input bad data.
If you find yourself needing complex validations to regulate the the data coming in from the form, a solution like this might not be what's in order and you might want to limit the scope of what is possible to do. Ryan's simple example here is spot on.
This dynamic nested form technique has worked wonders for me (Thanks, Ryan!) but I've been bitten by applying it to the wrong use cases-- use discretion when deciding on a UX.
I think you should have mentioned Cocoon
I'm using Cocoon... it seems pretty good so far.
Cocoon is cool
cocoon is cool
Hi
Can someone help me here. I am new with rails and trying to dynamically add fixed number of pre-populated nested forms using cocoon. Please be kind enough to read more details here.
http://stackoverflow.com/questions/15072932/dynamically-adding-fixed-number-of-prepopulated-nested-forms
Thanks a lot!!
thanks Ryan...
@anyone Does anyone have an example carrierwave intregration (file or image upload in in a nested model)
controller:
View:
Amazing how much simpler this is, especially since the power shown in the unrevised editions is one of the thing that made me think Ruby was so much better than the alternatives. Thanks, Ryan!
I actually feel good about spending the $9 per month for episodes like this! That's a big statement considering how cheap I am.
How do i get it to work with simple form?
Use Cocoon :) https://github.com/nathanvda/cocoon
Thank you Ryan. I like this nested model forms that starting from scratch. This is awesome.
+1
If you want more flexibility, try awesome_nested_fields. =)
+1 with awesome_nested_fields. It's got very detailed wiki
I just tried using you gem...it works great but I cant delete child objects even after setting allow_destroy: true....pls do you have any sugestions?
easy fix...got me disturbed for 30mins..I added :dependent => :destroy...maybe you want to add this to you documentation just to be prevent another person (newbie i suppose) from running around.
has_many :phones, :dependent => :destroy
accepts_nested_attributes_for :phones, allow_destroy: true
Thanks. Awesome gem!
Does anyone know how you would make the questions answerable (perhaps assuming that you were using Devise for user authentication and had access to current_user)? I'm guessing that you would have a model that stored the ID from a User model as well as an ID from the Answer model. So then on the show page, each answer that was listed would be a link that would allow the user to answer the question.
So i guess my question is: What code would you use to then save this into the database when the user clicked the link?
Also, is this the best way to go about this? should this actually use a form instead? It seems like an easy thing to do but I'm not sure of what the Rails way to approach it is. Thanks!
See: https://github.com/mark-d-holmberg/sed/tree/master/app/models
awesome, thanks!
Nice, thanks Mark. Does anyone else have any other examples?
What is the difference between Cocoon and awesome_nested_fields?
awesome_nested_fields is more flexible (you can put the code anywhere) and has an JS Callbacks and API.
Any reason not to use your nested_form gem anymore?
I was wondering this also?
Me too ?
These posts are over a year old, did anyone find out as to why to use the techniques in this episodes rather than the nest_form gem?
I'm getting in this episode the same strange thing some other user mentioned in another thread. It seems it's cut off in the end, interrupting Ryan mid-sentence... Probably just a few seconds of video cut off but I think it's worth mentioning.
Great episode as always.
Same thing happened to me when watching this and Episode #343.
What if you wanted to put a validation on Question to ensure that it's not blank... or maybe validate its uniqueness against all of the other Questions to ensure none of the names are the same?
The validations are easy, but the hard part is correlating those Rails errors to which Question input actually failed in the case of multiple children errors. If you had several questions that each were non-unique or perhaps blank, Rails will simply merge all of those errors into one key, and you have no way of associating those out independently from one another.
Does anyone know a workaround on this problem?
THANK YOU! I wrote my college Software Engineering project using the old version of this video, and this new approach makes it so much simpler! Keep them coming.
Awesome update on this technique, Ryan. And thanks everyone for the additional gem suggestions (cocoon and awesome_nested_fields).
How this would work when the models are associated via a has_many :through association?
I'm trying to follow the same steps, however nothing is displayed in my form.
I remember that the first episode regarding this topic used to build the objects in the controller, e.g. Question.new, so that they would be made available in the view. I found really weird that this wasn't mentioned this time.
Did that behavior changed in Rails?
In order to make it work with has_many :through I need to build "by hand" the associated object in my controller?
Thanks :)
I'm also having an issue with my model that contains a has_many :through association.
It would be nice to see this approached in the video... though that might be asking too much in your scope of the tutorial.
EDIT: I actually don't have a problem with my has_many :through... it works fine. I found that my coffescript had its indents wrong and was throwing an error. Once the coffeescript was fixed everything works like a charm.
thanks for your good work!
Haha, I'm still having a through association issue...see below — any pointers??
After this Railscast I found out that internally Rails is handling the build of the associated object when needed. It seems that this behavior has in fact changed.
The only thing I needed to add is a instantiation of my join model to the action 'new'.
I have a Proposal model which can have many Product through a join model called ProductEntry.
In the action 'new' from my ProposalsController I simply added:
This is just to display the form field when no ProductEntry is available yet, which is always the case when I'm creating a new Proposal.
When I go and edit a Proposal, Rails automatically instantiate all ProductEntry that are associated. If I edit any of those ProductEntry (such as the quantity attribute that I have), it simply works too.
Yeah, I also had issues getting the form fields to show up if I didn't put anything in the controller.
My user model had a profile model. The relationship was has_one and belongs_to.
I had to add the following to the users controller.
Users Controller
Hi Ryan,
Thanks for all the great RailsCasts - I'm learning a ton of stuff!
I'm using your adding/deleting field partials fairly extensively and ran into a couple of things others may find useful:
Your .gsub('\n','') removing newlines causes slight horizontal shifting of fields on inline forms. This was easily fixed by escaping rather than removing newlines using .gsub('\n','
').
jQuery won't recognize events from controls created this way. Apparently the solution is to use .on() (formerly .live and .delegate) though I have yet to try this.
Thanks again for all your great tutorials and keep up the good work.
Cheers,
Peter
I think the proper way to prepare the fields HTML is as follows:
and then define
escape_html_attribute
as follows:This prevents the
&
in

from being escaped.In Rails 3.0.3 I get "undefined method `klass'" from the application_helper.
This is the syntax I'm using:
Is my syntax correct? Does "klass" work with my rails version?
Thanks
Your problem might be the same issue as mine. The object.send(association) doesn't seem to work for has_one relationships.
Anyone else have this issue or a solution?
Thanks
Using Rails 3.2.3, I did have this error but it is fixed (see below for changes):
You can see I was using different variable names than the example, but hopefully the comparison between the two code snippets below will indicate what might be worth changing in your code.
ERROR
undefined method `klass' for nil:NilClass
BEFORE CHANGES
AFTER 2 CHANGES (no more errors)
I hope that is helpful to some folks.
Thanks for these truly awesome tutorials.
Thank you @LucasCioffi, changing the location of my link_to_add definitely fixed the undefined method error!
I just came across this issue. It is as you expected: object.send(association) does not work the same way for has_one as it does for has_many. To get around this, I changed the link_to_add_fields helper as follows:
Basically, I changed
f.object.send(association).klass
tof.object.class.reflect_on_association(association).klass
and, since I use users/_fields.html.erb instead of user_fields.html.erb, I also changed the render line. Hope this helps, if you're still having that problem. If not, hope this helps some other lost soul of the future.-Christian B.
Quick Q Ryan - the models I'm working with are connecting using has_many :through, and I'm getting issues with creating the sub-objects via the update method, here's the exception:
For context, Quizzes have many questions through a join table.
Anyway, decent chance I'll have this fixed before anyone has a chance to reply, but seemed like something enough people might be trying to do to warrant a comment.
Back to figuring it out.. :D
Figured it out, key was using the actual join relationship rather than the target of the join, then everything pretty much "just worked"
I won't lie though, this also helped (from a comment on the second part of the complex forms casts) : http://pastie.org/987614
I am having the same issue, and still not clear how you resolved it, can you paste your before and after code?
Thanks!
I am having the same issue! Could you elaborate further on how you solved it?
Great tutorial as always. I did run into a problem though when trying to implement it into my app. When I add an extra field it didn't show up in the params sent to the controller.
I found the problem was I had put the form into a table and it didn't work well with this. I simply removed the table and it all started to work.
This is working great for me except for one issue. I have SEVERAL nested models.
A workout has_many steps, a step has_many actions, an action has_many instructions. When I click to add a new step, I would like that step to be populated with on action fieldset, and that action fieldset, populated with one instruction fieldset. But it just renders the empty step fieldset, I have to click the "add action" and then the "add instruction" buttons for those to render. Does anyone know how to get all the nested fieldsets to render when I add a step?
Data Associations:
has_many steps
In case anyone is interested, I was able to achieve this behavior outside of the controller, by just "clicking" the add_field buttons with js
You can accomplish this on the server side by building the nested object in your view. Use the "build_(association name)" method, which is provided by Active Record.
Inside the
_action_fields.html.erb
partial:Now the
fields_for :action
block will execute and render theaction_fields
partial.Naturally you would want to use this in the sub-nested partials as well.
Hi Dan, would you please share how you did this? Thanks
I am having trouble using auto-complete with multiple fields. The first one works but the second instance does not. Been working on trying to figure out how to make it work for close to a week now. Any help would be great!
Please note I do NOT want to tokenize. Do in face want to set other fields along side the auto-complete text field too.
Thanks!
I'm trying to add an image field to my survey. I can get the image to upload and to show on the Show page. But when I go back to the Edit view, there is no image and I still see the "No file chosen" text next to the Choose File button.
I have this line of code in my Show view:
<%= image_tag question.image_url(:thumb).to_s if question.image? %>
but if I try to put that into the _form view then I get an unknown variable or method error.
I've tried a couple of if statements but haven't gotten it to work.
Thanks to anyone who can help.
@Charlie, were you able to get your issue to work, regarding "No File Chosen"? I'm trying to have that text hidden until a file is uploaded.
I got an error on jquery:
$("form").on is not a function
I upgrated jquery to 1.7.1, but it still error.
Thanks to anyone who can help.
Thanks for this brilliant tutorial! I am new to rails and this one made a few pennies drop.
How can I achieve that destroying a question automatically destroys all associated answers records in the database?
figured it out with
:dependent => :destroy
Hi, I followed the tutorial step by step
but my remove function won't work.
add function work fine, remove using checkbox works fine. Why?
Seems there's something wrong with the coffee indent. I'm new to this. What's wrong with it?
i'm trying to render a partial form in a show view but it doesn't render it, do you know why would this be?
I was able to get grandchildren to work in the forms with a special application helper function:
Essentially, you have to create the grandchildren in this helper to have an object for the fields_for to attach to.
I tried adding this method for adding grandchildren but I get the error:
undefined method 'klass' for nil:NilClass
passing in:image
as the child_association. Could you possible post your form code?I got this figured out and posted the answer here: http://stackoverflow.com/questions/16839555/rails-cast-196-197-nested-model-generation/16867048#16867048
How would you do this if your model is not ActiveRecord based? Since I'm not using ActiveRecord, I don't have access to the accepts_nested_attributes_for method.
Great Railcast. There seems to be a problem rendering the nested model fields when implementing this solution with models that have a one-to-one association. One-to-many associations show nested model fields fine, but not one-to-one.
Hi Jesus H. Did you ever figure this out? I'm having the exact same issue. Thanks!
I'm not sure if it's exactly the same thing, but what really saved me (for what I needed) was this https://github.com/moo-li/Simple-parent-child-forms-in-Rails-3.1
Great railcast anyways!
I'm getting a
Missing partial
in thelink_to_add_fields
method and can't for the life of me figure out why. I've followed the setup exactly as described in the RailsCast.It seems to be coming from this line:
Never mind, typo in the partial file name......
You know you can delete your comments if you find out your question isn't helpful to the others anymore, right?
I was hoping so, but all I can see is Reply. It appears you can only Delete within a certain timeframe.
This is a great piece of knowlege, thanks!
I encountered one problem.
The dynamic form doesn't work when I added
validates :question_id, presence: true
to the Answer model class.Form is not saving and returning error: Questions answers question can't be blank
This happens only in case when you try to add a new question and add a new answer to it.
Why is this happening?
I encountered this too!.. any solutions so far?
Just ran into this as well. Anyone found a decent workaround?
If you, like me, had trouble converting the Coffeescripts to pure Javascripts, this site is very helpful:
http://cs2js.nodejitsu.com/
I like this one even more.
Why is CoffeeScript so popular these days?
I figured out how jQuery works and now I have to start over and learn Coffeescript :-(
Anyone got this working with mongoid?
Never mind. Works fine with Mongoid.
Great tutorial, Ryan!
I was lucky enough to get this working on my machine.
The only problem I have is that the nested attributes are not saved to the database in the order in which I created them.
E.g. sometimes I create 3 answers at once, then click "Update" and the answers do appear on the form, but not in the correct order. I can't see any pattern in there, so I assume that they get saved to the database randomly.
Is there any way to fix this?
I created a migration to add a position:integer field, used a hidden_field inside partial with :class => 'position' and included this line of js before event.preventDefault() to the .add_fields event:
> $(this).prev().find('.position').val(time)
and on has_many association, i used
Thank you for this :)
Hi guys, nice episode.
Ryan, I think that the following code could help handling validation errors.
What do you think?
Thanks,
Mauro
Sweet.. I was looking for this... Thanks!
Base on this example, How do we delete an entire survey together with it's questions and answers? Please help...
Well, you could add
:dependent => :destroy
to eachhas_many
association. and then simply delete your Survey!I would like to add a 'Copy' button that creates a new copy of the question with the same set of answers. I think it will be similar to the link_to_add_fields, but I cannot figure out how to capture user input and create a new nested object with those values on the fly. Any help will be appreciated. Thanks.
Did you find help for this? I, too, would like to copy the record above to create a new record - like an Excel sheet...
in our scenario we need to vary the number of associated records allowed. We have validation in the model i.e
accepts_nested_attributes_for :answers , :limit => 4,:allow_destroy => true
My question is . how do we prevent the Add Answers link from being rendered if we already have reached our limit ?
I'm having some trouble adapting railscasts with nested parameters using strong_parameters. I think this form creates an empty hash in answers_attributes and questions_attributes which cause problems on update for strong_parameters.
In order for this to work with Rails 4.0 or later, you have to use http://blog.trackets.com/2013/08/17/strong-parameters-by-example.html and make following changes to
app/controllers/survey_controller.rb
Few other changes are required in
GemFile
and some other files:
I'm using the
gem nested_form
- it's great! But there's a (beginner) problem I have with its output. The fields_for<%= f.fields_for :news_item do |report| %> ... <% end %>
seems to wrap everything in it in a
<div class="fields">...</div>
. How to avoid this?I will add "reject_if" for the "accepts_nested_attributes_for" method for, ( for example) omit some attributes (for example blank attributes)
I get a ReferenceError: event is not defined loading the page as soon as I add the code to implement "remove" in javascript. From Firebug:
(function() {
jQuery(function() {
$('form').on('click', '.remove_fields', function(event) {});
$(this).prev('input[type=hidden]').val('1');
$(this).closest('fieldset').hide();
return event.preventDefault();
});
}).call(this);
Anyone have any idea what's going on? Any help appreciated.
I follow the tutorial closely but my "Add Question" does not work. When I click on it, nothing happens. When I look into Chrome developer tool, it does not seem like the javascript is executed. Can anyone advise? What are the things I could possibly miss?
Maybe you have a lib conflict, I had to try with some adjustments to the Js code and It worked for me, also i had to put it in the application.js obviously there is other problem there, but at least is working
This is my code:
$('form').on ('click', '.add_fields',
function(event) {
time = new Date().getTime()
regexp = new RegExp($(this).data('id'), 'g')
$(this).before($(this).data('fields').replace(regexp, time))
event.preventDefault()}
)
I've solved the problem, my problem was that the js.coffee file wasn't been included in the application.js file, that explains why the converted js worked directly on the application.js file, I had to added manually //= require ....js.coffee in the application.js file because i've removed the require_tree directive.
In the current Rails 4 beta, the
:child_index
option forfields_for
doesn't work. Use:index
instead.Nevermind, Rails 4 beta as of today is back to using
:child_index
.What if no associated records exist? How would I use this in a new form where neither table has any records, to create new records?
How could I accomplish this sort of thing with a single model? I want to create several records at once with an "Add Another Record" button, but I'm only using a single model, not nested...
I'm using this technique to add/edit multiple people to/in a household. It's a rails 4 application using turbo links along with query.turbolinks.
My application also uses jQuery datepicker plugin.
My _person_fields partial includes a date field that uses the date picker plugin, but it doesn't work. The datepicker is not being initialized in the dynamically added person_fields partials.
I've tried several methods from the Turbolinks episode with no success.
This is beyond my familiarity, but I think I need to somehow call document ready after the person_fields partial is added. Don't know how to do that.
Any suggestions are appreciated. Thanks!
I am having the exact same issue. I think the reason is that the date field is not getting assigned the class that is needed for the JS to kick in.
I have no idea how to go about fixing this, but if I cannot find a way to do this then I will have to try going to a none dynamic way of adding a new nested record, as I will need the fields created with the correct class assigned to them.
Hopefully someone with more skill than myself can come up with a good solution for this.
Has anyone tried creating the nested forms but allowing only a certain limit of answers or number of questions? Ideally, I would like the jQuery to disable the add link for new question or answer if the number of questions has reached the maximum for that user.
Hi Ryan, thanks for the great screencast, worked like a charm!
I have a small question though:
I use the add_fields strategy to add an extra row to a table of records in a nested form. However, the td's don't get rendered correctly, because they are put into 'data', which does not render the td's (the entire table row is rendered in the first td of the row).
Any ideas on how to tackle this? I would like to continue using the table to maintain overview...
Any suggestions are greatly appreciated!
Hi everyone, I had a problem with my Nested Model From, I am not sure what did I do wrong,
When I try to render the from, the nested form field does not appear. Is there any problem with my codes ?
Hi @dedek, you code looks ok to me. Just make sure you are actually instantiating a
task
in your controller, something like thisGood luck!
when you're generating your models, don't forget to add the reference id of the parent model. aka:
class Task < ActiveRecord::Base
belongs_to :project
attr_accessible :description, :done, :project_id
end
I am getting a ArgumentError wrong number of arguments (3 for 1), when I call the link_to_add_fields helper method. I've placed it outside of the block for fields_for, like so:
I'm using rails 4.0 beta. Anyone have any idea why this could be happening?
EDIT: figured out that it's coming from the arguments passed to fields_for here:
why doesn't fields_for accept more than one argument?
Disregard this, I had defined fields_for in a custom form builder and it was overriding the default implementation.
Everything works for me as it should, locally. When I push to heroku, the add question button does not work... It just redirects me to the '#'. I am having issues with it randomly locally, but if I change the class name in the js and helper to 'add_field' from 'add_fields', everything seems to work fine.
First I had an issue with the page caching and every question and answer was created twice.
3 days of troubleshooting now. Good technique, but Cocoon may be the way to go with this one.
Figured it out! Assets were not compiling correctly. Ignore my previous comment, although this showed me how hard this was to debug. Thanks for the great learning resources Ryan.
What did you do to get your assets to compile correctly? I think I am having the same issue.
So did you find what the problem was? Because i have the same problem right now.
I'm having the exact same problem. Did anyone find a solution?
I had the same problem. Didn't quite figure out what was causing it, but upgrading the gem file to Rails 4 fixed it. Just add/update these gems.
I added the following to development.rb:
Hi James,
I know it's long ago that you had the problem that every question and answer was created twice but I have the same problem at the moment and don't know how to solve it. Do you maybe still know how you solved it?
Thanks
Flo
Hi,
I've downloaded the example code and I am unable to get the remove and add links to work. The remove check_box works fine. Since the same code works on my friends machine I believe the problem may be related to the way rails is configured on my computer. When I click the remove link a get the following http://localhost:3000/surveys/1/edit#
(note the # sign after the edit).
Can anyone suggest possible reasons for this?
Sincerely,
Lisa
This is the default behavior when clicking on a link with an href="#". Make sure that whatever javascript your using to add or remove fields includes an
event.preventDefault()
call. In coffeescript, this should look something like the following for nested fields but can easily be applied to any click event where you need to suppress the default behavior for a given event:I'm having the same exact problem. The code is solid, becuase if I do a refresh on that page, then my remove & add starts to work.
It's as if the javascript hasn't quite loaded yet.
Any ideas for the slow load of Javascript? Using ruby 2, rails 4.
Hey Lisa,
I figured it out: Turbolinks.
Take a look at Episode 390 (http://railscasts.com/episodes/390-turbolinks).
The way Ryan has written the code, it should be compatible with turbolinks; I think it's turbolinks that needs some work.
Basically I had to add a 'data-no-turbolink' attribute within one of my html tags. I tried to use a tight scope of div tags around the most troublesome coding, and worked out wider and wider (parent to parent) until it finally worked.
Unfortunately, I had to move so far out, I might has well put my data-no-turbolink in the 'body' tag. :(
I might just end up removing turbolinks. Good Luck, and I hope this helps someone else in this similar mess.
Great advise Eric! you save me a lot of time.
The jQuery Turbolinks gem fixed the problem for me.
I have the exact same problem you did. I tried your Tubrolinks suggestion, but it doesn't work.
Where did you add the 'data-no-turbolink' tag?
UPDATE: I have it working now - I had my answer_fields wrapped in a tag rather than a tag
Thanks for your post though, turbolinks is very cool!
I'm having the exact same problem. I tried Eric Wanchic's answers below regarding Turbolinks, but it didn't seem to help.
Since it's trying to execute the actual link to the '#' url, my guess is that for some reason the
event.preventDefault()
is not working because it is still trying to execute the link rather than running the javascript.Anyone know how to fix it?
Is it just me, or it doesn't work in 2.0?
PS> It's turbolinks. See my post to Lisa up above. ^^^
Great screencast. Glad to see it has been revised.
However, this solution only works for simple types of forms/associations. It becomes far more complicated (and confusing) to try and create a form like this that allows you to create different types of associations, each with their own set of fields (i.e. TextareaQuestion, MultipleChoiceQuestion, each subclassing a generic Question class). Almost like a polymorphic form builder.
I'm working on trying to create this type of form. It doesn't feel like this type of thing is supported very well by Rails form helpers. I'm having the same difficulty using the simple_form gem.
Essentially, you need to create a drill-down that allows you to select the type of association you want to create, then display the form fields relevant to the type you have selected.
It would be nice to see an example of this. I bet Ryan Bates would have a nice, clean way to accomplish this. =]
This is a great screencast. As a newbie to RoR these are invaluable.
After adapting the code to my project, I couldn't get the '.add_fields' js function to work. Clicking the link to add a child record did nothing.
I checked the web browser console and found this error when the page loaded: "TypeError: 'undefined' is not an object (evaluating '$(this).data('fields').replace')"
After struggling with it for a while I realized my indents were not set properly in the jQuery script. I feel like I need a beer...
Good screencast. However, one thing left out that was mentioned in the original ones is the
:reject_if => :all_blank
in the model.Ok, so I downloaded the source code, and when a survey is updated, the params are this:
{"utf8"=>"✓",
"_method"=>"put",
"authenticity_token"=>"yO16xiTDvjH1i4mvgUSK3XiDxiyzHM87PSGZAc57Cu4=",
"survey"=>{"name"=>"Rails Survey",
"questions_attributes"=>{"0"=>{"content"=>"kjhlkjh",
"_destroy"=>"0",
"answers_attributes"=>{"0"=>{"content"=>"kjlk",
"_destroy"=>"false",
"id"=>"2"}},
"id"=>"2"}}},
"commit"=>"Update Survey",
"id"=>"1"}
But I created a rails app from scratch following line by line in the railscast and I get an arror "Cannot convert Symbol into Integer" and my params are slightly different when updating a survey:
{"utf8"=>"✓",
"_method"=>"put",
"authenticity_token"=>"I4IByp+jkutbWSHRM8z5zvLoKQ1AxfoyNhdMxJ02ORg=",
"survey"=>{"name"=>"Test 1",
"questions_attributes"=>{"content"=>""}},
"commit"=>"Update Survey",
"id"=>"1"}
So I have a feeling it has to do with the "0" that is before the "content" of "questions_attributes" in the source code params but not in my params. What am I doing wrong and how can I fix it?
Hi,
a newbie question. Got two models Job and Company. A company has_many jobs and each job belongs_to company. Building a form for Job which has collection select that allows user to select already existing company or create one with three fields i.e. name, info, and logo. So far all i have seen is accepts_nested_attributes_for being used in the form of model with has_many relationship and not belongs_to. I saw ryans create model through textfield railscast and this one but couldn't figure out which approach to go for. I like the create model through textfield but how to create three fields rather than one. Any suggestion would be highly appreaciated.
I don't think it's necessary to call the klass method to get a new object in the helper. We can call #new or #build on the association directly like this:
One point that is probably obvious for most people, but confused me at first was why we would need to swap the object_id that's set in the helper for a time value in the javascript. I was thinking along the lines of: "the object_id is already unique, right?"
Well, yes and no. A unique object_id will be generated each time the helper is called to create an "add_fields" link. But that link may then be clicked multiple times. Each time it's clicked, it's going to generate a collection of nested fields named with the same object_id. Then of course, when the form is saved only one of those records is going to be created.
Have you tried calling #build as you mention? That seemingly innocent change somehow sends me into an infinite recursive loop; that is to say, link_to_add_fields gets called over and over again. I can't imagine how building the new object through the association would have this side effect. Here is the line of code before the change:
after:
Any ideas?
Nevermind. I found where the recursion was happening...
I had the same question, isn't the
object_id
already unique? Thank you for writing your comment, I didn't even have to write out the code to find out for myself.There's something i'm having trouble understanding. How are the new objects being created in the link_to_add_fields helper method without making a call to the server?
As I understand, each click on the Add questions link calls the helper method. But how is the ruby code parsed when we are on the client side?
Also, I put a debugger in the function and saw it doesn't get called on clicking the link. Can anyone give a nice explanation on how this is working Client-Server wise? I'm a bit mixed up... :-/
Thanks!
The
link_to_add_fields
helper is called server side before the page is sent to the client.If you look at the
link_to_add_fields
helper you will see that it generates alink_to
at the bottom. This is the link that the client clicks on, not thelink_to_add_fields
helper method.Great screencast as always! I run into a problem though. Can't make it work to add fields. After click on "add" the browser jumps to the top and no field is added. Remove field is working.
Anyone had the same issue, and figured it out?
http://stackoverflow.com/questions/20136241/nested-model-forms-railscast-196-revised-adding-fields-via-jquery-not-worki
Thanks!
this guy makes the same but updated to use strong_parameters :
http://iroller.ru/blog/2013/10/14/nested-model-form-in-rails-4/
hope this help someone.
thanks chreyes you saved my day.
does any one know how to make something like this work with 2 none nested models? for example I have user model that has one profile(model) and one car(model)
both profile and car models are nested under user but car and profile has no relationship. I figure I can do a form_for user and use both field_for profile/car but is there a better way to do this?
actually nvm i figured it out I just used a form_for :car(replace with your model name)
then call current_user.create_car etc... in my profile controller.
with added strong param for car params
now I'm wondering if I can make this cleaner with method mission or delegate so I don't have to chain methods so much in controller
Okay - so this railscasts is very useful, however I have a scenario that I need help with. Say I just want to create a Task list with no associated Task List/Project Name. So I have only one model and want the user to be able to enter multiple Tasks as they wish. How would I go about doing so?
Ryan, thanks for the Railscast, very good and just what I needed. I seem to have this working with one issue. When I create a new nested record I have two fields that are using a datepicker class and then new records (I am guessing) don't have this class attached to them.
Would anyone know how to go about getting this fixed in a dynamic enough way? Would really like to get this working.
Many thanks.
I had trouble getting the example code from GitHub running (ran into many of the issues mentioned throughout these comments). So I went ahead and created a new version of the Questionnaire app based on Rails 4 that implements strong parameters in the surveys controller in place of Rails 3 attr_accessible, and fixes the issue with Turbolinks. The rest is largely identical to the RailsCast example. Works great for me, though please feel free to submit issues or fixes if you'd like.
Working Rails 4 version:
https://github.com/dnewkerk/nested-model-form
If anyone happens to try out the Rails 4 example on iroller.ru mentioned a few comments above, note that I think the params aren't quite right in that example (log shows unpermitted parameters errors). You need to add :id as well as :_destroy to survey_params. Also you shouldn't need to add the questions controller.
Hope this helps!
dnewkerk, you are a champ. Thanks for you all your effort :)))))
Thanks a lot.
I <3 you. Thank you! Nesting the attributes for the answers INSIDE of the attributes for the question inside of the parameters for the survey... I never would've figured it out in a million years.
I followed the tutorial of
Nested Model Form (revised)
http://railscasts.com/episodes/196-nested-model-form-revised?view=commentsWhich is about how to create a survey with multiple models,
But I wonder how to make to survey cab be a real survey.
Let user can answer those questions and I can gather the user's feedback.
I've done the nested form by referencing to http://railscasts.com/episodes/196-nested-model-form-revised?
I can fill three models' data in one form now,
But How to saving the form data and make it available to re-fill the form ?
The relations of the models is 'One survey has many questions,and one question has many answers,'
My roughly thinking is, save all the
survey_params
insurveys_controller.rb
Maybe I should create a new model
FormRecord
to keep all the form records,And when user comes to the form-page next time,
it'll selecting all the records he made,
and provide a checkbox and button to let him decide which form-data record he wants to fill the form.
But I have no idea what kind of the data structure I should have,
And How to fill the form via Javascript.
Is there any idea ? or reference ?
I'm having trouble with the remove link in production. The fieldset remove works however it still triggers validation even though it is no longer visible on the screen. Am i missing a step?
I am using the "link_to_add_fields" helper as used in this screencast in my "Order" model, in the order form you can "add row". It all works ok. But when editing an order, example: /order/1/edit", if the form had 5 rows, when I save the edits it saves the form with 10 rows, if form has 3 rows it saves it with 6 etc. Anybody else run into this issue?
Ah came across the cause, needed to add the order rows :id to my permitted parameters. All good now.
http://stackoverflow.com/questions/18946479/ror-nested-attributes-produces-duplicates-when-edit
Hi Ryan
Just wanted to say thank you very much for an excellent video. Hope you are doing well and that you soon have enough energy to return to railscast.
Hi,
Im pretty new to Rails, and Im using Cocoon.
I would like to know if instead of setting the association to 'people', I could somehow get an specific one, like Person.find(id) when using link_to_add_association
Hello all, I'm currently following this guide and I'm running into a problem with the first remove answers step.
<%= f.label :content, "Answer" %>
<%= f.text_field :content %>
<%= f.hidden_field :_destroy %>
<%= link_to "remove", '#', class: "remove_fields" %>
jQuery ->
$('form').on 'click', '.remove_fields', (event) ->
$(this).prev('input[type=hidden]').val('1')
$(this).closest('fieldset').hide()
event.preventDefault()
when I go to test this and click on the "remove" link nothing is hidden. when I submit the form it doesn't remove the answer. Any thoughts?
Hello. Ho could we set nested params inside controller method, if we have many nested params, so that we should iterate over them an set their values to something. I have asked about that here:
http://stackoverflow.com/questions/29901150/how-to-set-values-of-nested-parameters-in-rails-4-from-controller-method
Hi I am new to Ruby on rails, I have followed this cast but i am running into a big issue now,
<%= mp.fields_for :projectmembers do |pm| %>
<%= render 'projectmember_fields', pm_form: pm %>
<% end %>
<tr><td class="addfld"><%= link_to_add "Add", mp, :projectmembers %></td></tr>
Here this render doesnt sends the local variable to the partial i am calling. but when i remove this link_to_add method it gets the local variable. Could you please help me on this
this is the query i have posted
link
Is this still relevant and working in the latest Rails?
After trying to make it work in my project for hours, I downloaded the source as a new project, ran db:setup and seed, and it doesn't work either (won't even load index without throwing a Nilclass error)
This episode has been updated to Rails 5 as a blog post Complex Forms in Rails 5.
Hi folks
was hoping for some advice:
My nested form is starting to become increasingly large and complex. I would like to collapse certain things. Is this possible?
Also is it possible to view only certain children via a drop down menu? any advice much appreciated.
rgds
Ben
Hi,
at first thanks for the great screencast.
Everything seem to work but I have the problem that after clicking on the add link TWO answers will be created.
Has anyone an idea how to solve this?
Thanks
Flo
Nice work
i hope can visit here regularly anymore
I liked the way of explaining this thing.