My local basketball league is currently using free software that has shortcomings and is littered with ads. So I'm working on a site where we can upload our game statistics, and is catered to us. It will have more functionality than our current site, no ads, and as a new basketball player I can track my growth. This article is going to dive into creating a customized associations in Rails that will streamline functionality for when I want to display games stats on the frontend.
I have a reference table called games that tracks two teams in my database, the home team and the away team. By keeping this relationship on one table I can make calls to the Game table and find out who the winner was.
rails g resource game home_team:references away_team:references
I'll start by running a generator for games. This will create my model, migration, and controller. I will only focus on the migration and model files as that's where our changes will need to happen. I don't have models called Home Team or Away Team (they are just a Team), so I need to tell Rails what those are and where to look.
Migration
In our generated migration file I need to change the ends of line 4 and 5. Here I am telling Rails: these columns are foreign keys of a table with a different name. Home Team and Away Team both point to the Teams table. The new code will be:
class CreateGames < ActiveRecord::Migration[6.0]
def change
create_table :games do |t|
t.references :home_team, null: false, foreign_key: {to_table: :teams}
t.references :away_team, null: false, foreign_key: {to_table: :teams}
t.references :season, null: false, foreign_key: true
t.timestamps
end
end
end
Model
I need our game model to belong to two teams. This has some conflicts with Active Records base functionality. Inherently belongs_to
is a one-to-one connection. I need to change some code here.
class Game < ApplicationRecord
belongs_to :season
belongs_to :home_team, class_name: 'Team', foreign_key: 'home_team_id', required: true
belongs_to :away_team, class_name: 'Team', foreign_key: 'away_team_id', required: true
end
Essentially I am creating an alias. Home Team is actually just a Team, and Away Team is a different Team. This allows me to work around the one-to-one connection of belongs_to
while achieving desired functionality.
Voila! I am now able to go into my rails console
and create some test data.
hTeam = Team.create(name: "Bears")
aTeam = Team.create(name: "Aces")
g = Game.create(away_team_id: aTeam.id, home_team_id: hTeam.id)
g.home_team
#=> <Team id: 1, name: "Bears", created_at: "2020-06-01 17:41:14", updated_at: "2020-06-01 17:41:14">
g.away_team
#=> <Team id: 2, name: "Aces", created_at: "2020-06-01 17:42:14", updated_at: "2020-06-01 17:42:14">
Top comments (0)