Right way to create a route

I have users, children, events and parents (yes this is really the
names). children and events belong to users. Parents belong to
children. this is what I have now:

map.resources :users do |user|
    user.resources :notes
    user.resources :events
    user.resources :children do |child|
      child.resource :parents

Is this the appropriate way to do this? If so then why am I having
problems with this:

def new
    @parent = current_user.children.parents.build

    respond_to do |format|
      format.html # new.html.erb
      format.xml { render :xml => @parent }

Thanks in advance for any help.

What do you mean by "problems"? What error do you get?

Also, have you added the appropriate has_many/belongs_to relationships
in the models?


Thanks for the response. Yes, the appropriate has_many, belongs_to
exist. Here is the problem:

undefined method `build' for [Object]:Array

RAILS_ROOT: /etc/rails_apps/custodypower
Application Trace | Framework Trace | Full Trace

28:in `new'

when accessing /user/x/children/x/parents/new

What you're looking for is ActiveRecord relationships, rather than

class User < ActiveRecord::Base
has_many :notes
has_many :events
has_many :children

class Child < ActiveRecord::Base
belongs_to :user
has_many :parents

class Parent < ActiveRecord::Base
has_many :children

def build
  # does something

Your routes should allow you to (with some coding in the controllers
to process the nested parameters correctly) use a URL such as this:



mlittle wrote:

undefined method `build' for [Object]:Array

It appears that you're somehow getting an Array that does not have the
extensions normally added to an association array by Rails. By
"extensions" I mean methods like build, create, and all the others added
by has_many associations:

RAILS_ROOT: /etc/rails_apps/custodypower
Application Trace | Framework Trace | Full Trace

28:in `new'

when accessing /user/x/children/x/parents/new

Assuming that the "new" method of the "parents_controller" is where the
path "/users/x/children/x/parents/new" should end up then your routes
are working just fine.

So this means your problem is somewhere else. My guess is (not having
information about how your models) the problem is somewhere in your
model layer.

Oh. You shouldn't need to call 'build' in order to get the parent
records, unless you define a method in the Parent class that does

@parent = current_user.children.parents

Or if a child can have multiple parents,
@parent = current_user.children.parents.first
@parent = current_user.children.parents.find_by_name(params

and so on.

This is for creating a new record

def new
    @parent = current_user.children.parents.build

    respond_to do |format|
      format.html # new.html.erb
      format.xml { render :xml => @parent }

This is incorrect? I have the appropriate belongs_to and has_one

Ah, I think I see the issue now. current_user.children will return a
collection of objects. You're then trying to ask for the parents of
every item in the collection. But you can't really do that.

Maybe you need to do something like
current_user.children.first.parents.build? But that doesn't quite
make sense either - the children collection might be empty, for

It feels to me like you're missing model somewhere here, somewhere
between current_user and the children collection. Otherwise, wouldn't
current_user "be" the parent?

In your models, what's the relationship between the user, the
children, and the parents?


This is the actual names, btw.

User > Children > Parent

A user owns the child and the child has a parent. I hope this makes
sense. A user has many children while a child has 1 parent.

My last message may not have made sense.

Users have many children while children only have one user. A child
only has one parent. I know this is confusing because these ARE the
actual names for my resources.

Users > Children > Parent (Singular)

I think Jeff is correct.

current_user.children is going to return an array. In order to create
a parent record, you'll need to somehow choose which child to add the
parent to. You'll have to watch out for nil values in relationships,
just as a warning.

curent_user.children.each {|child| child.parent = Parent.create }
@parents = current_user.children.map {|c| c.parent } # returns an
array of parents, one for each child

The fact that you have your routes set up may give you more options.
For example, if you have a parents_controller, then maybe this
functionality could go there?


in parents_controller:
def new
  user = User.find(params[:user_id]) # or current_user if this isn't
done with routes
  child = user.children.find(params[:child_id])
  @parent = Parent.build
  child.parent = @parent


If you were to just do child.parent.build, you'd get a NoMethodError
because child.parent may be nil, and NilClass does not have a 'build'