Rails 3 Retrieving All Great Grandchild Records As ActiveRecord Collection

1.5k views Asked by At

So I'm trying to perform queries on a models great granchildren. The relationship is as so...

Tournament > Competitions > Matches > Players

and the Tournament model:

class Tournament < ActiveRecord::Base
  has_many :competitions, :dependent => :destroy
  has_many :matches, :through => :competitions
  has_many :players, :through => :matches

end

Currently what I have for retrieving all the great great grandchildren records is:

@results = @tournament.competitions.collect{|b| b.matches.collect{|c| c.players.with_win_count}}.flatten

And this works, however the problem is that it returns an array. What I'm trying to do is build a dynamic query based on user input, and the player table is essentially a result pool for all matches and the user has the option to filter only what he wants to see. What I have in the end is a fairly potentially complex (depending on user input) query and the additional where clauses cannot be performed on an array. To give you a better idea of how this is meant to work, here is my code...

def results
   @tournament = Tournament.find(params[:id])
   @results = @tournament.all_great_grandchildren
   @results.where(params[:player_condition1]) if params[:player_condition1]
   @results.where(params[:player_condition2]) if params[:player_condition2]
   @results.where(params[:player_condition3]) if params[:player_condition3]

   if params[:match_condition]
     #Join to match table so we can query the match fields
     @results.join(:match)
     @results.where(params[:match_condition])
   end
   ....
   @results.order(params[:order]) if params[:order]
end

Is there a way to find all of the great grandchildren (player) records for any given tournament without an array so I can continue to condition the records?

2

There are 2 answers

2
Chamnap On BEST ANSWER

I think you should just call @tournament.players will work out of the box if you have setup with the above associations.

0
Wally Glutton On

Chamnap has got it. The reason we define “has_many” and “belongs_to” associations in models is to give us easy access to the association models.

So when you have a Tournament object called tournament, you can do

competitions = tournament.competitions
matches = tournament.matches
players = tounaments.players

You can also go in the reverse direction, starting with a player object. Ex: matches = player.matches

With Active Record you shouldn't have to do manual joins or raw SQL model calls when dealing with associations. Have a quick read of the Actice Records Associations guide:

http://guides.rubyonrails.org/association_basics.html