belongs_to structure has_one
-
30-09-2019 - |
Question
I ai une application qui présente les caractéristiques suivantes
There are Clubs Each Club has Teams Each Team has Players
J'ai une table d'utilisateurs. Le tableau utilisateur contient essentiellement le nom d'utilisateur et mot de passe pour le gestionnaire de club, responsable de l'équipe et le joueur à se connecter au système.
Comment dois-je structurer les modèles et les tableaux?
Je prévois de créer des tables pour Club, équipe et les joueurs. Mais je ne suis pas sûr show de structurer la relation entre eux et la table des utilisateurs.
Je pourrais créer user_id
dans chacun des modèles, mais la relation serait Club belongs_to User
qui ne semble pas juste. De plus, je finirais avec un modèle de l'utilisateur qui a les éléments suivants
has_one :club
has_one :team
has_one :player
Ce qui ne va pas. Un utilisateur aura qu'un seul d'entre eux à un moment donné.
Y at-il une meilleure façon de structurer?
La solution
Sous Rails, has_one
est vraiment « a au plus un ». Il est parfaitement valable d'avoir trois décorateurs de has_one
à User
. Si vous voulez vous assurer qu'ils ne disposent que précisément l'un, vous pouvez ajouter une validation, par exemple:
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
Puisque vous avez la possibilité de changer la table des utilisateurs dans la base de données, je pense que je mettrais club_id
, team_id
, player_id
à users
, et ont les éléments suivants:
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
Je serais même tenté de renommer User
comme Manager
, ou ont has_one :manager, :class_name => "User"
dans les modèles Club
, Team
et Player
, mais votre appel.