问题
I have an application which has the following characteristics
There are Clubs Each Club has Teams Each Team has Players
I have a users table. The user table basically contains the username and password for the club manager, team manager and the player to login to the system.
How should I structure the models and the tables?
I plan to create tables for Club, Team and Players. But I am not sure show to structure the relationship between them and the users table.
I could create user_id
in each of the model, but the relationship would be Club belongs_to User
which doesn't seems right. Moreover I would end up with a User model that has the following
has_one :club
has_one :team
has_one :player
Which is not right. A user will have only one of them at any given time.
Is there a better way to structure this?
回答1:
Under Rails, has_one
is really "has at most one". It's perfectly valid to have all three has_one
decorators in User
. If you want to ensure they only have precisely one, you could add a validation, for instance:
class User < ActiveRecord::Base
has_one :club
has_one :team
has_one :player
validate :has_only_one
private
def has_only_one
if [club, team, player].compact.length != 1
errors.add_to_base("Must have precisely one of club, team or player")
end
end
end
Since you have the ability to change the users table in the database, I think I would put club_id
, team_id
, player_id
in users
, and have the following:
class Club < ActiveRecord::Base
has_one :user
has_many :teams
has_many :players, :through => :teams
end
class Team < ActiveRecord::Base
has_one :user
belongs_to :club
has_many :players
end
class Player < ActiveRecord::Base
has_one :user
belongs_to :team
has_one :club, :through => :team
end
class User < ActiveRecord::Base
belongs_to :club
belongs_to :team
belongs_to :player
validate :belongs_to_only_one
def belongs_to_only_one
if [club, team, player].compact.length != 1
errors.add_to_base("Must belong to precisely one of club, team or player")
end
end
end
I'd even be tempted to rename User
as Manager
, or have has_one :manager, :class_name => "User"
in the Club
, Team
and Player
models, but your call.
来源:https://stackoverflow.com/questions/3556322/belongs-to-has-one-structure