Reputation: 27862
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
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,
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
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