Я пытаюсь использовать бизнес-модель, очень похожую на ту, что описана здесь , используя STI.

class Person < ActiveRecord::Base
   # identified by email
end

class Owner < Person
end

class Customer < Person
end

class Employee < Person
end

class Store < ActiveRecord::Base
   belongs_to :owner
   has_many :customers
   has_many :employees
end

Приведенные выше классы описывают то, что я собираюсь делать. Проблема здесь в том, что Сотрудник никогда не может выступать в качестве Заказчика и нанимать услуги, предоставляемые магазином, в котором он работает, или даже другим магазином, если только не создается новая запись, представляющая того же человека, действующего в качестве другой роли в другом магазине. контекст. Это не очень СУХОЙ, но я не знаю, есть ли лучшее решение.

Здесь? У кого-нибудь есть предложения о том, как я могу решить эту проблему?

Большое спасибо.

2
Marcelo 24 Дек 2013 в 22:13

2 ответа

Лучший ответ

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

Это оставляет нам пять компонентов:

  1. Люди.
  2. Магазины.
  3. Отношения «человек владеет магазином».
  4. Отношения «человек - покупатель магазина».
  5. Отношения «человек - сотрудник магазина».

На самом деле все три отношения являются отношениями «многие-ко-многим». Также обратите внимание, что где-то в поле зрения есть ИППП; это хорошо, STI почти всегда (IMO) является ошибкой, поэтому вы должны начать подвергать сомнению свою модель данных и свое суждение, как только они обнаруживаются. У ИППП, конечно, есть свое место, но вы должны хорошо подумать, чтобы оправдать их всякий раз, когда они возникают.

Это оставляет нам две довольно простые модели (Person и Store) и три отношения "многие ко многим" между людьми и магазинами. Стандартными способами моделирования отношений "многие ко многим" с помощью ActiveRecord являются has_many ... :through и has_and_belongs_to_many. Если вам нужно работать с одним из отношений «человек-магазин» как с отдельным объектом (например, с сотрудником с номером сотрудника, почасовой ставкой, налоговыми записями и т. Д.), Вам, вероятно, понадобится has_many :through; если вам нужна только ассоциация, то, вероятно, подойдет has_and_belongs_to_many.

Некоторые ссылки:

3
mu is too short 24 Дек 2013 в 19:03

Фактически, это СУХОЙ с точки зрения кода. На самом деле я работаю над очень похожим проектом с использованием STI, где у нас есть пользователи, менеджеры и администраторы, и в базе данных должно быть по три записи для каждой. Это СУХОЙ с точки зрения Rails, потому что каждая из этих записей имеет свои собственные уникальные атрибуты, методы в своих классах и т. Д., Но разделяют общий код из модели, аналогичной той, что вы называете Person . На самом деле я думаю, что это хороший способ сделать это, если вы используете ИППП.

Альтернативой может быть общий код в модуле, который вы можете включить в каждый из Customer, Employee и Owner.

Другой альтернативой (скорее всего, что я бы сделал, если бы начал с нуля) было бы иметь одну таблицу Person и использовать роли, используя cancan и, возможно, даже rolify. Таким образом, вы имеете дело с одним классом, который называется Person, где экземпляр Person может иметь одну или несколько ролей, например customer, employee или owner.

0
CDub 24 Дек 2013 в 18:52