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     end end

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 }     end   end

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?

Jeff purpleworkshops.com

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

/etc/rails_apps/custodypower/app/controllers/parents_controller.rb: 28:in `new'

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

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

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

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

class Parent < ActiveRecord::Base has_many :children

def build   # does something end end

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

/user/1/children/5/parents

-sax

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: http://www.railsbrain.com/api/rails-2.3.2/doc/index.html?a=M001885&name=has_many

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

/etc/rails_apps/custodypower/app/controllers/parents_controller.rb: 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 something.

@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 [:parent_name])

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 }     end   end

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 example.

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?

Jeff

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?

/users/1/children/1/parent/new

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

  ... end

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' method.