принадлежит_к имеет_одну структуру

У меня есть приложение, которое имеет следующие характеристики

There are Clubs
Each Club has Teams
Each Team has Players

У меня есть таблица пользователей. Таблица пользователей в основном содержит имя пользователя и пароль для менеджера клуба, менеджера команды и игрока для входа в систему.

Как мне структурировать модели и таблицы?

Я планирую создать таблицы для клуба, команды и игроков. Но я не уверен, что нужно структурировать отношения между ними и таблицей пользователей.

Я мог бы создать user_id в каждой из моделей, но отношение было бы Club belongs_to User, что кажется неправильным. Более того, я бы получил модель пользователя, которая имеет следующее

has_one :club
has_one :team
has_one :player

Что неправильно. У пользователя будет только один из них в любой момент времени.

Есть ли лучший способ структурировать это?


person Addy    schedule 24.08.2010    source источник
comment
Непонятно, что представляет собой Пользователь. Если у Клуба есть Команды, а у Команды есть Игроки, что такое/ Пользователь? Что у него есть, что у него есть?   -  person Chowlett    schedule 24.08.2010
comment
Извините за это .. Я отредактировал вопрос, чтобы уточнить таблицу пользователей.   -  person Addy    schedule 24.08.2010
comment
Ах я вижу. Пользователь по сути является менеджером одного из Клубов, Команд или Игроков. У вас есть возможность изменить таблицу пользователей в БД?   -  person Chowlett    schedule 24.08.2010
comment
Да, я могу изменить таблицу пользователей, если это необходимо. Я использую restful-authentication для входа пользователей из этой таблицы.   -  person Addy    schedule 24.08.2010
comment
В порядке. Я отредактировал свой ответ ниже.   -  person Chowlett    schedule 24.08.2010


Ответы (1)


В Rails has_one действительно "имеет не более одного". Вполне допустимо иметь все три декоратора has_one в User. Если вы хотите убедиться, что у них есть только один, вы можете добавить проверку, например:

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

Поскольку у вас есть возможность изменить таблицу пользователей в базе данных, я бы поместил club_id, team_id, player_id в users и получил следующее:

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

У меня даже возникло бы желание переименовать User в Manager или добавить has_one :manager, :class_name => "User" в модели Club, Team и Player, но вам решать.

person Chowlett    schedule 24.08.2010
comment
Я подумал о добавлении трех идентификаторов в таблицу пользователей. Как мы можем идентифицировать объект, который вошел в систему? Для каждого пользователя будет только один из club_id, team_id или player_id. Я проверю все три, чтобы узнать, принадлежит ли пользователь к клубу, команде или игроку. Есть ли лучший способ перейти от модели User к модели Club/Team/Player? - person Addy; 24.08.2010
comment
Я подозреваю, что вы могли бы сделать что-то умное с abstract_class? или полиморфной ассоциацией; но я был бы склонен просто иметь такой метод в пользователе, как def managed ; club || team || player ; end - person Chowlett; 24.08.2010