Hommer Smith
Hommer Smith

Reputation: 27862

Dynamic associations with Rails?

I am a little bit confused in defining the model design for the current project I am working on.

It's a sport team management app, so I can have teams from different sports adding players. Since for each sport I want to store different information for the players, I have thought on having the following model.

A team:
-> has_many soccer_players
-> has_many basketball_players
-> ...

But this seems repetitive and I will just have lots of has_many, one for each sport type. My question is, since at the time a User creates a team, he will choose the sport type, I would just need to define an association. So if the team is a soccer team, I would just need the 'has_many soccer_players'.

How could I do that? Or even better, how would I model this in a better way?

Thanks

Upvotes: 2

Views: 1962

Answers (2)

gmaliar
gmaliar

Reputation: 5489

Following what Zippie offered and what you have asked in the comment I offer a slightly modified version.

I'll break it down to phrases and then into ruby classes and associations, so if you want to make it truely polymorphic,

  • A Team has many Players
  • A Team has many Team Attributes
  • A Player has many Attributes

It might simplify some parts of our application. Team model itself for validations and such. You'd have to decide what are generic attributes and what are dynamic, for instance name, weight, height are generic because all players have them, so they can be inside your Player model and not inside your Attribute model.

So we can now have something of the sort of:

class Team < ActiveRecord::Base
  has_many :players
  has_many :attributes, :as => :attributable
end

class Player < ActiveRecord::Base
  belongs_to :team
  has_many :attributes, :as => :attributable
  attr_accessible :name, :weight, :height
end

class Attribute < ActiveRecord::Base
  belongs_to :attributable, :polymorphic => true
  attr_accessible :name, :value
end

As of your other question

You would have one table of attributes, one table of players and one of teams essentially. Creating a football team and players (football = soccer yes?) would be like so (let's decide we already created a team):

player = Player.new
player.name = 'Lionel Messi'
player.attributes << Attribute.create!(:name => :playing_position, :value => :second_striker)
@team.players << player
@team.attributes << Attribute.create!(:name => :uefa_cups, :value => 4)

Your migration would look something like this (taken from Rails Guides directly - with minor changes):

class CreateAttributes < ActiveRecord::Migration
  def change
    create_table :attributes do |t|
      t.string :name
      t.string :value
      t.references :attributable, :polymorphic => true
      t.timestamps
    end
  end
end

Upvotes: 1

Zippie
Zippie

Reputation: 6088

Maybe something like:

team:

has_many :type_of_sports, :through => type_of_sport_on_team
has_many :players, :through => types_of_sports

type_of_sport:

has_many :teams, :through => type_of_sport_on_team
has_many :players

type_of_sport_on_team:

belongs_to :team
belongs_to :type_of_sport

player:

belongs_to :type_of_sport

after additional info:

Class Player < ActiveRecord::Base
     attr_accessible :name, :surname, :age
end

Class BasketballPlayer < Player
     attr_accessible :free_throw_average
end

Class SoccerPlayer < Player
     attr_accessible :penalty_scores
end

Upvotes: 0

Related Questions