Полиморфная установка ИППП - PullRequest
1 голос
/ 05 марта 2011

У меня есть приложение, которое широко использует модель Entity.

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

  • Одной из моделей была Entity, которая связана с проектами и имеет несколько типов (клиент, запросчик, поставщик и т. Д.).

  • Другой моделью была Addressbook, которая в основном идентична сущности, за исключением другой таблицы и названия модели и нескольких полей только для адресной книги (например, отключено).

В настоящее время у нас есть столбец для объекта для addressbook_id, чтобы отобразить объекты проекта обратно в адресную книгу, или мы не можем выполнить сопоставление на основе адреса электронной почты. Данные между адресной книгой и объектами НЕ синхронизируются, то есть необходимо иметь возможность обновлять объект в проекте без какого-либо влияния на данные в адресной книге (хотя мы также предоставляем возможность обновления адресной книги).

Независимо от того, существует 4 или 5 типов сущностей. Они имеют в основном одинаковые поля (имя, фамилия, адрес электронной почты, адрес, телефон и т. Д.). Каждый тип сущности может иметь от 1 до 3 полей, уникальных для него, но это все. В дополнение к этому в текущем приложении могут быть люди или компании (та же таблица STI, которая также имеет поле company_name).

Для того, что приложение должно сделать, легко найти все объекты для проекта (независимо от типа, будь то люди или компании) - это победа. Также можно легко объединять объекты в запросе и искать их по проекту.

Из-за этого я склонен придерживаться модели STI и сохранять ее простотой, и, поскольку каждый тип разделяет 90% одинаковых полей, это не большая трата. Тем не менее, мне любопытно, есть ли какое-нибудь хорошее предложение для решения всей проблемы, состоящей в том, чтобы иметь по существу одинаковые модели как для Адресной книги, так и для сущности, но хранить данные в отдельных таблицах. Я размышлял о том, как может помочь полиморфная ассоциация, но я думаю, что это усложнит структуру таблицы и может снизить производительность запросов (довольно большой набор данных, где эти объекты могут быть включены в представления списка).

Но на самом деле я не хочу заканчивать этим ...

class Entity

class Customer < Entity

class Addressbook

class AddressbookCustomer < Addressbook

etc...

Не очень СУХО, и между типами сущностей и подтипами есть общие функциональные возможности (например, у Entity и Addressbook будет метод имени, который возвращает полное имя, а у Customer и AddressbookCustomer может быть метод last_order). 1026 *

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

Есть предложения?

1 Ответ

0 голосов
/ 05 марта 2011

Я никогда не делал этого, но если вы хотите поделиться кодом между всеми вашими "сущностями", почему бы не создать один базовый класс, от которого все остальные наследуют:

class OneClassToRuleThemAll < ActiveRecord::Base
  def name
  ...


class Entity < OneClassToRuleThemAll
  set_table_name "entities"

class AddressBook < OneClassToRuleThemAll
  set_table_name "address_books"

Это дает вам один базовый класс для разделяемых методов, но отдельные таблицы для каждой ветви в вашем дереве наследования.

Если вам не нравится это решение, потому что вы все еще хотите делиться методами, которые не принадлежат OneClassToRuleThemAll, но совместно используются классами двоюродных братьев и сестер ниже по дереву, то почему бы не написать небольшой модуль для хранения этих такие функции, как last order, а затем просто импортировать этот модуль в каждый из классов двоюродных братьев, которым нужны эти функции?

P.S. Я даже не знаю, сработает ли первый пример, но думаю, что так и должно быть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...