Rails Form with Three Models and a Namespace

Putting your head on it for a long time. On Rails 2.3.2, Ruby 1.9.1.

An attempt to use one form to create three objects that have these relationships:

class Person has_one :goat end class Goat belongs_to :person has_many :kids end class Goat::Kid belongs_to :goat end 

Here is a brief description of the circuit:

 Person first_name last_name Goat name color Goat::Kid nickname age 

I would like my #create action #create create new instances of all three models with the specified associations. However, although it seems that the my params hash is passed to the controller as it should (based on the backtrace logs in the browser when it explodes), the Goat::Kid object does not collect the parameters.

irb (an irb session is just a pseudo-representation of what I'm trying to accomplish, so if it doesn’t call #save! or any other things, it really doesn’t mean that it’s correct. I am trying to do this through a browser / web form.)

 a = Person.new :first_name => 'Leopold', :last_name => 'Bloom' b = Goat.new :name => 'Billy', :color => 'white' c = Goat::Kid.new :nickname => 'Jr.', :age => 2 a.goat.kids >> [] 

Now I can’t understand how to get a view, to pass parameters to each object and force the controller to save these parameters in db.

My questions are: A) is this a good place to use nested_attributes_for , and if so, how do I declare this with a namespace? B) Is there a much simpler and clearer way to do this?

Switching parameters to the three models was very difficult for me, and no matter how many documents I read, I can’t circle my head around it ( #form_for and #fields_for ). The namespace further complicates this. Thanks for any help!


Addendum: if I declare

 accepts_nested_attributes_for 

What is the correct way to use a character argument for a model with names?

 accepts_nested_attributes_for :kids, :through => :goats 

or

 accepts_nested_attributes_for :goats_kids, :through => :goats 

or

 accepts_nested_attributes_for :goats::kids, :through => :goats 

I'm not sure how models with names translate into their character identifiers. Thanks!

+1
source share
1 answer

Ok, this is my first time playing with accepts_nested_attributes_for , but after playing a bit, I was able to get something to work.

First install the model:

 class Person < ActiveRecord::Base has_one :goat accepts_nested_attributes_for :goat end class Goat < ActiveRecord::Base belongs_to :person has_many :kids accepts_nested_attributes_for :kids end class Goat::Kid < ActiveRecord::Base belongs_to :goat end 

With a simple soothing controller:

 ActionController::Routing::Routes.draw do |map| map.resources :farm end class FarmController < ApplicationController def new end def create person = Person.new params[:person] person.save render :text => person.inspect end end 

Then a semi-complex form arises:

Next, setting the form:

 <% form_for :person, :url => farm_index_path do |p| %> <%= p.label :first_name %>: <%= p.text_field :first_name %><br /> <%= p.label :last_name %>: <%= p.text_field :last_name %><br /> <% p.fields_for :goat_attributes do |g| %> <%= g.label :name %>: <%= g.text_field :name %><br /> <%= g.label :color %>: <%= g.text_field :color %><br /> <% g.fields_for 'kids_attributes[]', Goat::Kid.new do |k| %> <%= k.label :nickname %>: <%= k.text_field :nickname %><br /> <%= k.label :age %>: <%= k.text_field :age %><br /> <% end %> <% end %> <%= p.submit %> <% end %> 

From looking at the source for accepts_nested_attributes_for , it looks like it will create a method for you called #{attr_name}_attributes= , so I needed to set up my fields_for to reflect this (Rails 2.3.3). Then, having got has_many :kids , working with accepts_nested_attributes_for . The kids_attributes= method kids_attributes= for an array of objects, so I needed to specify the array association in the form manually and tell fields_for which model to use.

Hope this helps.

+2
source

All Articles