Help with Routes

I have the following models

entity    has_many :locations    has_many :sites, :through => :locations

location    belongs_to :entity    belongs_to :site

site    has_many :locations    has_many :entities, :through => :locations

AND routes:

  map.resources :entities do |entity|     entity.resources :locations,                           :collection   end

What I wish to do is to display all of the locations for a given entity. I have modified locations_controller to this:

  # Limit locations list to just the parent entity   before_filter :load_entity

  # GET /locations   # GET /locations.xml   def index     @locations = @entity.locations.find(:all) ...   private

  def load_entity     @entity = Entity.find parms[:entity_id]   end

And in views/entities/index.html.erb when I have this:

    <td>       <%= link_to 'Locations', entity_location_path -%>     </td>

Then I get this:

entity_location_url failed to generate from   {:controller=>"locations", :action=>"show"}    - you may have ambiguous routes, or you may need to supply      additional parameters for this route. content_url has      the following required parameters:      ["entities", :entity_id, "locations", :id]    - are they all satisfied?

If I have this in index.html.erb instead:

    <td>       <%= link_to 'Locations', entity_location_path(entity),              :method => 'index' -%>     </td>

Then I get this:

entity_location_url failed to generate from   {:controller=>"locations", :entity_id=>#<Entity id: 1,     entity_name: "my first client", entity_legal_name: "My First Client Ltd.",     entity_legal_form: "CORP", created_at: "2008-03-25 22:41:43",     updated_at: "2008-03-25 22:41:43">, :action=>"show"}, expected:   {:controller=>"locations", :action=>"show"}, diff:   {:entity_id=>#<Entity id: 1, entity_name: "my first client",     entity_legal_name: "My First Client Ltd.", entity_legal_form: "CORP",     created_at: "2008-03-25 22:41:43", updated_at: "2008-03-25 22:41:43">}

Which sends me back, as far as I can tell, to the first form of the call. Can someone straighten me out with respect to the proper link_to call to use?

James Byrne wrote:

  map.resources :entities do |entity|     entity.resources :locations,                           :collection   end

This incudes the route: entity_location GET /entities/:entity_id/locations/:id                               {:controller=>"locations", :action=>"show"}

So:

    <td>       <%= link_to 'Locations', entity_location_path -%>     </td>

Then I get this:

entity_location_url failed to generate from   {:controller=>"locations", :action=>"show"}    - you may have ambiguous routes, or you may need to supply      additional parameters for this route. content_url has      the following required parameters:      ["entities", :entity_id, "locations", :id]    - are they all satisfied?

This is saying that the route is missing both :entity_id and :id to complete a route match.

If I have this in index.html.erb instead:

    <td>       <%= link_to 'Locations', entity_location_path(entity),              :method => 'index' -%>     </td>

Then I get this:

entity_location_url failed to generate from   {:controller=>"locations", :entity_id=>#<Entity id: 1,

Here, you can see that you are now supplying :entity_id but you still need to supply the :id parameter (which is the particular location for this entity you want to GET).

Since you are clearly after the index method, then you need to pluralise the "location" part of the helper name:

link_to 'Locations', entity_locations_path(entity)

Mark Bush wrote:

Here, you can see that you are now supplying :entity_id but you still need to supply the :id parameter (which is the particular location for this entity you want to GET).

Since you are clearly after the index method, then you need to pluralise the "location" part of the helper name:

link_to 'Locations', entity_locations_path(entity)

Thank you. I am now past this point and running into another problem. In the locations_controller I have this for my new method:

  def new

    @location = @entity.build_location

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

However, when I call this from views/locations/index.html.erb

<%= link_to 'New location', new_entity_location_path( params[:entity_id] ) %>

Then I get this:

undefined method `build_location' for #<Entity:0x4df2ad8>

I was under the impression that the build_location method was automatically generated in consequence of the have_many attribute in entity.rb.

But, playing around in the console disabused me of that notion. What methods I have for locations in Entity are:

- location_ids - location_ids= - locations - locations=

I infer that locations is an array.

James Byrne wrote:

I infer that locations is an array.

It is an association object which includes the Enumerable module and so behaves like an array.

For a has_many/belongs_to relationship, you can add new records from both sides of the relationship. In your case:

class Entity   has_many :locations

class Location   belongs_to :entity

You can add a new location to an entity's locations:

e = Entity.find :first e.locations.build ... e.locations.create ...

And you can create a new entity that a location will point to:

l = Location.find :first l.build_entity ... l.create_entity ...

Mark Bush wrote:

It is an association object which includes the Enumerable module and so behaves like an array.

For a has_many/belongs_to relationship, you can add new records from both sides of the relationship. In your case:

class Entity   has_many :locations

class Location   belongs_to :entity

You can add a new location to an entity's locations:

e = Entity.find :first e.locations.build ... e.locations.create ...

This is the bit I was missing. I was trying to use e.build_location.