(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

Eduardo Yáñez Parareda wrote:

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

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.