(REST) Nested routes

Hello, I’m in troubles with nested routes. I have three models: Team,
Tournament and TeamTournaments

class Team < ActiveRecord::Base
has_many :tournaments, :through => :team_tournaments
has_many :team_tournaments

class TeamTournament < ActiveRecord::Base
belongs_to :team, :foreign_key => ‘team_id’
belongs_to :tournament, :class_name => ‘League’, :foreign_key =>
‘tournament_id’

class Tournament < ActiveRecord::Base
has_many :teams, :through => :team_tournaments
has_many :team_tournaments

So it’s a N-M relationship between Team and Tournament through
TeamTournaments.

Well, I want to have nested routes from Team to Tournament:

teams/1/tournaments/1

so I’ve mapped it in routes.rb:

I’ve tried these two forms:
map.resources :teams, :has_many => [:tournaments]
map.resources :teams do |team|
team.resources :tournaments
end

And I can do http://localhost:3000/teams/1/tournaments/1, but I can’t
use tournament_url(:team_id => @team, :id => @team.leagues[0]) in a
view because I get the error tournament_url is not defined.

What’s wrong?

If I’m not mistaken,

map.resources :teams, :has_many => [:tournaments]
map.resources :teams do |team|
team.resources :tournaments
end

does exactly the same thing… so I think you only need the first line
(at least in Rails 2.0).

The fact that tournaments_url doesn’t get recognized is because the
only way you have it routed is when it’s scoped by a team.

You would need to scope it with a team in order to get a proper url,
(e.g. team_tournament_url(@team, @tournament). You may be looking to
get routes for both directions so then you need to define your routes
as such:

map.resources :teams, :has_many=>[:tournaments]
map.resources : tournaments, :has_many=>[:teams]

It’s late and I’m not 100% thinking through your situation, so take it
with a grain of salt.

-Jason

You would need to scope it with a team in order to get a proper url,
(e.g. team_tournament_url(@team, @tournament).

Yes, that’s right, I forgot to prefix tournament_url with ‘team_’. As
always, Rails is more easier than anybody could think.

Thanks Jason.

hi there, i have a problem…
i have 3 tables as below
class1 - id, classname
student - id, class1_id
timetable - class1_id

im having a problme to convert sql to ruby-readable sql.
can u assist me?
i want to have something like…
the output will show the timetable of the student… by define the
class first.
please help me… thanks

On Jan 27, 5:36 pm, “Eduardo Yáñez Parareda” [email protected]

Eduardo Yáñez Parareda wrote:

Hello, I’m in troubles with nested routes. I have three models: Team,
Tournament and TeamTournaments

I see Jason found the problem for you. If you get confused over routes
again, just use the “rake routes” command to see all your routes and
their names. It’s the best way to know what’s going on when you do
map.resources.

class Team < ActiveRecord::Base
has_many :tournaments, :through => :team_tournaments
has_many :team_tournaments

class TeamTournament < ActiveRecord::Base
belongs_to :team, :foreign_key => ‘team_id’
belongs_to :tournament, :class_name => ‘League’, :foreign_key =>
‘tournament_id’

class Tournament < ActiveRecord::Base
has_many :teams, :through => :team_tournaments
has_many :team_tournaments

By the way, those models look like they could be cleaned up a little.

class Team < ActiveRecord::Base
has_many :team_tournaments, :dependent => :destroy
has_many :tournaments, :through => :team_tournaments

class TeamTournament < ActiveRecord::Base
belongs_to :team
belongs_to :tournament, :class_name => ‘League’

class Tournament < ActiveRecord::Base
has_many :team_tournaments, :dependent => :destroy
has_many :teams, :through => :team_tournaments

I added the :dependent option, which cleans up the join model records
when they are no longer useful because one of the records being joined
no longer exists. The other thing I changed was removing the
:foreign_key option on the belongs_to associations. The :team
association would never need to explicitly specify that, and in Rails 2
neither would the :tournament. I’m a little confused what’s going on
with setting the :class_name to League, but I assume you have some STI
going on that I can’t see.


Josh S.
http://blog.hasmanythrough.com