Rails 3: я должен использовать STI или просто дополнительный столбец? (ищет совета) - PullRequest
3 голосов
/ 30 мая 2011

Я работаю над проектом (Rails 3.0.3), где я думаю, что мне может понадобиться использовать STI, но я не уверен, должен ли я просто добавить дополнительный столбец в таблицу и покончить с этим.

В моей объектной модели (для игровой системы) у меня есть игроки (которые принадлежат агентствам) и владельцы (которые владеют агентствами).

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

Вместо этого я должен был назвать агента «пользователь», упс.Итак, у меня есть следующее:

class Agency < ActiveRecord::Base
  has_many :players, :class_name => "Player", :foreign_key => "agency_id"
  has_many :agents, :through => :players, :source => :agent_id
  has_one :owner, :class_name => "Owner", :foreign_key => "agency_id"
end

class Player < ActiveRecord::Base
  belongs_to :agency, :class_name => "Agency", :foreign_key => "agency_id"
  belongs_to :agent, :class_name => "Agent", :foreign_key => "agent_id"
end

class Owner < ActiveRecord::Base
  belongs_to :agency, :class_name => "Agency", :foreign_key => "agency_id"
  belongs_to :agent, :class_name => "Agent", :foreign_key => "agent_id"
end

Игрок и Владелец имеют одинаковые атрибуты, единственное различие между ними заключается в том, что Владелец имеет разные отношения с Агентством, чем Игрок (Владелец владеет Агентством,Агентство имеет только одного Владельца, но имеет много игроков).

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

С точки зрения чистого ООПOwner является подклассом Player (или Owner и Player являются подклассами некоторого неопределенного класса, такого как участник или что-то в этом роде), но при учете постоянства кажется плохим дизайном базы данных иметь отдельные таблицы игроков и владельцев.

Моей первой мыслью было реорганизовать и использовать STI и сделать Owner подклассом Player или ввести новый базовый класс, а затем создать подкласс как Owner и Player.

Другая моя мысль заключалась в том, что я мог бы просто добавить логическое значение/ tinyint столбец Player называется is_owner, но я могу предвидеть, что потенциальноприводя к некоторому неприятному представлению и коду контроллера.

Мне было интересно, сталкивался ли кто-либо с подобными обстоятельствами и, возможно, имеет какой-либо совет или мог бы указать мне некоторые хорошие онлайн-ресурсы для чтения по STI?

1 Ответ

1 голос
/ 24 февраля 2012

Может быть, вы должны думать о Player и Owner как об отношениях между Agent и Agency. Таким образом, Agent владеет и Agency, а Agent играет в игры и Agency. Следовательно, вы можете ввести понятие роли и, следовательно, модель Role, от которой наследуются Player и Owner. Вопрос в том, хотите ли вы когда-нибудь использовать модель Role? Или ваше заявление о владельцах и игроках и, кроме некоторых общих признаков, это две совершенно разные вещи?

Если это две разные вещи, то вы должны сделать их двумя разными моделями. Если у вас есть некоторое дублирование кода между двумя моделями, вы можете использовать (или несколько) mixin (s) для совместного использования кода между ними.

В целом я предпочитаю композицию наследованию. Во-первых, наследование выглядит как элегантный способ обмена кодом между классами, но речь не об этом. Наследование касается типов и интерфейсов. Следовательно, вы соединяете вещи с точки зрения их интерфейсов. Это сильное ограничение в дальнейшем развитии ваших моделей.

Я использую наследование, только если существует реальное отношение is_a, а не отношение shares_some_code_with между классами. И что еще более важно: я использую его тогда и только тогда, когда он имеет техническое преимущество для меня. В противном случае есть гораздо лучшие способы обмена кодом между классами в ruby.

...