I’m finding Rails quite difficult conceptually. People tell me one day the light will dawn and it will all seem perfectly natural. At the moment though it seems like there’s 1000 ways to achieve any given objective, but only one right one. If you choose one of the other 999 then you’re in a world of manual coding as a result.
I couldn’t find a really basic example of nested forms: a parent record with an arbitrary number of child records. Here’s my attempt to create the simplest possible parent-child forms, with the minimum configuration and the maximum convention. Rails experts: I’d love to reduce this even further – please give me any suggestions for doing so.
The resulting forms can be cloned directly fromĀ https://github.com/moo-li/Simple-parent-child-forms-in-Rails-3.1, but here’s how to create them yourself:
- At the command prompt, create a new Rails application:
rails new myapp(wheremyappis the application name). If you want HTML5
goodness thenrails new myapp -m https://github.com/russfrisch/h5bp-rails/raw/master/h5bp.rb. cd myapprails g scaffold Mom name:stringrails g model Kid name:string mom:references- Add the following lines to
app/models/mom.rbhas_many :kids, :dependent => :destroy accepts_nested_attributes_for :kids, :allow_destroy => :true
rake db:migrate- In
config/routes.rb, changeresources :momstoresources :moms do resources :kids end
rails g controller Kids- Add the following methods to
app/controllers/kids_controller.rbdef create @mom = Mom.find(params[:mom_id]) @kid = @mom.kids.create(params[:kid]) redirect_to mom_path(@mom) end def destroy @mom = Mom.find(params[:mom_id]) @kid = @mom.kids.find(params[:id]) @kid.destroy redirect_to mom_path(@mom) end
- Add the following lines to
app/views/moms/show.html.erbbefore the line
containing<%= link_to 'Edit', edit_mom_path(@mom) %> |<h2>Kids</h2> <%= render @mom.kids %> <h3>Add kid</h3> <%= render 'kids/form' %>
- Create a file
app/views/kids/_kid.html.erbwith the following code:<p> <strong>Kid:</strong> <%= kid.name %> <%= link_to 'Remove', [kid.mom, kid], :confirm => 'Really remove kid?', :method => :delete %> </p>
- Create a file
app/views/kids/_form.html.erbwith the following code:<%= form_for([@mom, @mom.kids.build]) do |f| %> <div class="field"> <%= f.label :name %> <%= f.text_field :name %> </div> <div class="actions"> <%= f.submit %> </div> <% end %> rails s- Point your browser to
http://localhost:3000/moms.
Thank you for that concise example. I found it quite helpful.
Rails code now uses shorthand for rendering the subform:
<%= render @mom.kids %>great post thanks, your right i’m not found a “simple information” this kind of issue and is so rare because is very common, thanks again & tomorrow i gonna a tried
Very helpful post! I have been looking all over the net for this and fortunately I found yours. Keep up the good work. Thank you soooooooooooooo much!
That a great example. Now how would you add validation on the kid name?
Could you maybe also explain how to “edit” the “Kid” please? Would be great!
Thanks for this. Simple and helpful example.
Awesome…!!!
Can you post simple App using couple of controls: Buttons, Radio buttons, list box. Thanks.
Appreciate if it is posted.
How would you create the mom and kid at the same time, or is that not possible?
Never mind, I was being over zealous with parent_id ( validates :parent_id, :presence => true ) will give you a headache if you try and do a nested create
This is great, thank you.