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.