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

James B. 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 …

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.

Mark B. 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.