1

I've been out of the rails dev world for a little while and am a bit rusty when it comes to setting up relationships and joins between tables, so apologies if this is a very simple question.

  • I have a Team model which has an id column.
  • I have a Match model which has home_team_id and away_team_id columns.
  • I'd like to be able to call @team.matches and have any Match where either the home_team_id or away_team_id equal the @team.id show up.

I can achieve it with the following query, but it's far from ideal.

@matches = Match.where(home_team_id: @team.id) || Match.where(away_team_id: @team.id))

So what's the recommended way to set up my models and relationships to achieve the above behaviour?

Thanks in advance!

Eyeslandic
  • 14,553
  • 13
  • 41
  • 54
Gareth Jones
  • 1,760
  • 1
  • 14
  • 24

3 Answers3

3

This is inspired by @Joel_Blum's answer. I think it's a bit cleaner and expands the utility through home_matches and away_matches scopes:

 class Match < ApplicationRecord
     belongs_to :home_team, class_name: "Team"
     belongs_to :away_team, class_name: "Team"
 end

 class Team < ApplicationRecord
     has_many :home_matches, foreign_key: :home_team_id, class_name: "Match"
     has_many :away_matches, foreign_key: :away_team_id, class_name: "Match"
 
     def matches
         home_matches.or(away_matches)
     end
 end
Kewei Jiang
  • 163
  • 4
0

I've done similar with the following in the model:

def matches
  Match.where('home_team_id = ? OR away_team_id = ?', self.id, self.id)
end

which at least gives you a scope. Then in your controller:

@matches = @team.matches

I'd be interested in any other ideas.

Ben Trewern
  • 1,583
  • 1
  • 10
  • 13
0

This is a possible model setup

 class Match < ApplicationRecord
     belogns_to :home_team, class_name: "Team"
     belongs_to :away_team, class_name: "Team"
 end

 class Team < ApplicationRecord
    has_many :matches,-> {
      unscope(:where).where(home_team_id: self.id).or(where(away_team_id: self.id))
    }
 end

And now @team.matches should just work. The only tricky part is getting the has_many to work with 2 foreign keys by doing unscope(:where)

Joel Blum
  • 7,750
  • 10
  • 41
  • 60