Почему все Active Record ненавидят? [закрыто]


103

По мере того, как я узнаю все больше и больше об ООП и начинаю реализовывать различные шаблоны проектирования, я постоянно возвращаюсь к случаям, когда люди ненавидят Active Record .

Часто люди говорят, что он плохо масштабируется (ссылаясь на Twitter в качестве основного примера), но на самом деле никто не объясняет, почему он плохо масштабируется; и / или как достичь плюсов AR без минусов (с помощью похожего, но другого шаблона?)

Надеюсь, это не превратится в священную войну паттернов проектирования - все, что я хочу знать, это **** конкретно ****, что не так с Active Record.

Если он плохо масштабируется, почему бы и нет?

Какие еще проблемы у него есть?


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

1
Реализация Active Record в Ruby больше похожа на ORM.
Джимми Т.

1
Существует социальный феномен, который заключается в том, что для того, чтобы получить признание, большее признание, казаться более умным и резким, люди склонны механически повторять любую шумиху отрицания любого текущего стандарта, модели, широко распространенных технологий, путая его с революционный прогресс к следующей волне.
Андре Фигейредо

Ответы:


90

Есть ActiveRecord Design Pattern и ActiveRecord ORM Library Rails , а также множество подделок для .NET и других языков.

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

Я знаком только с ActiveRecord от Rails, я постараюсь рассмотреть все жалобы, которые были подняты в связи с его использованием.

@BlaM

Проблема, которую я вижу с Active Records, заключается в том, что это всегда примерно одна таблица

Код:

class Person
    belongs_to :company
end
people = Person.find(:all, :include => :company )

Это генерирует SQL LEFT JOIN companies on companies.id = person.company_idи автоматически генерирует связанные объекты Company, чтобы вы могли это сделать, people.first.companyи ему не нужно было обращаться к базе данных, потому что данные уже присутствуют.

@ pix0r

Неотъемлемая проблема Active Record заключается в том, что запросы к базе данных автоматически генерируются и выполняются для заполнения объектов и изменения записей базы данных.

Код:

person = Person.find_by_sql("giant complicated sql query")

Это не рекомендуется, поскольку это некрасиво, но в тех случаях, когда вам просто нужно написать необработанный SQL, это легко сделать.

@ Тим Салливан

... и вы выбираете несколько экземпляров модели, вы в основном делаете "выбор * из ..."

Код:

people = Person.find(:all, :select=>'name, id')

При этом будут выбраны только столбцы имени и идентификатора из базы данных, все остальные «атрибуты» в сопоставленных объектах будут просто равны нулю, если вы вручную не перезагрузите этот объект и так далее.


Могущественный! Я не знал об этой особенности. Еще один аргумент в пользу дополненной реальности, который я должен поставить в свой арсенал.
Тим Салливан,

Присоединение выходит за рамки шаблона Active Record.
Джимми Т.

"Person.find_by_sql" вообще не является шаблоном Active Record. Его в значительной степени "Активная запись" меня подвела, поэтому мне нужно исправить это вручную.
magallanes

52

Я всегда обнаруживал, что ActiveRecord хорош для быстрых приложений на основе CRUD, где Модель относительно плоская (например, не много иерархий классов). Однако для приложений со сложной объектно- ориентированной иерархией DataMapper , вероятно, является лучшим решением. Хотя ActiveRecord предполагает соотношение 1: 1 между вашими таблицами и вашими объектами данных, такого рода отношения становятся громоздкими с более сложными доменами. В своей книге о шаблонах Мартин Фаулер указывает, что ActiveRecord имеет тенденцию выходить из строя в условиях, когда ваша модель является довольно сложной, и предлагает DataMapper в качестве альтернативы.

Я убедился, что это правда. В случаях, когда у вас много наследования в вашем домене, сложнее сопоставить наследование с вашей СУБД, чем сопоставить ассоциации или композицию.

Я делаю это так, чтобы иметь "доменные" объекты, к которым ваши контроллеры получают доступ через эти классы DataMapper (или "уровень обслуживания"). Они не отражают базу данных напрямую, а действуют как объектно-ориентированное представление некоторого реального объекта. Предположим, у вас есть класс User в вашем домене, и вам нужно иметь ссылки или коллекции других объектов, уже загруженные, когда вы извлекаете этот объект User. Данные могут поступать из множества разных таблиц, и шаблон ActiveRecord может сделать это очень сложно.

Вместо прямой загрузки объекта User и доступа к данным с помощью API в стиле ActiveRecord код вашего контроллера извлекает объект User, например, путем вызова API метода UserMapper.getUser (). Именно этот модуль отображения отвечает за загрузку любых связанных объектов из соответствующих таблиц и возвращение завершенного объекта «Домен» пользователя вызывающей стороне.

По сути, вы просто добавляете еще один уровень абстракции, чтобы сделать код более управляемым. Содержат ли ваши классы DataMapper необработанный пользовательский SQL, вызовы API уровня абстракции данных или даже доступ к самому шаблону ActiveRecord, на самом деле не имеет значения для кода контроллера, который получает красивый заполненный объект User.

Во всяком случае, вот как я это делаю.


5
Похоже, вы просто не знакомы с ActiveRecord. «ActiveRecord предполагает соотношение между вашими таблицами 1: 1». Совсем неправда. ActiveRecord обладает всеми видами потрясающей реляционной магии. См. Api.rubyonrails.org/classes/ActiveRecord/Associations/…
tybro0103 04

16
@ JoãoBragança - возможно, вместо саркастического комментария вы могли бы на самом деле объяснить трудности, которые возникают при сегментировании данных - чтобы остальные из нас могли кое-чему научиться :)
Taryn East

11

Я думаю, что существует очень разный набор причин между тем, почему люди «ненавидят» ActiveRecord, и тем, что с ним «не так».

Что касается ненависти, то есть много яда по отношению ко всему, что связано с Rails. Что касается того, что с этим не так, вполне вероятно, что это похоже на все технологии, и есть ситуации, когда это хороший выбор, и ситуации, когда есть лучший выбор. По моему опыту, ситуация, когда вы не можете воспользоваться преимуществами большинства функций Rails ActiveRecord, - это когда база данных плохо структурирована. Если вы обращаетесь к данным без первичных ключей, с вещами, которые нарушают первую нормальную форму, где для доступа к данным требуется множество хранимых процедур, вам лучше использовать что-то большее, чем просто оболочку SQL. Если ваша база данных относительно хорошо структурирована, ActiveRecord позволяет вам воспользоваться этим.

Чтобы добавить к теме ответа комментаторам, которые говорят, что в ActiveRecord что-то сложно, с помощью реплики фрагмента кода

@Sam McAfee Предположим, у вас есть класс User в вашем домене, и вам нужно иметь ссылки или коллекции других объектов, уже загруженных при получении этого объекта User. Данные могут поступать из множества разных таблиц, и шаблон ActiveRecord может сделать это очень сложно.

user = User.find(id, :include => ["posts", "comments"])
first_post = user.posts.first
first_comment = user.comments.first

Используя параметр включения, ActiveRecord позволяет вам переопределить поведение отложенной загрузки по умолчанию.


8

Мой длинный и запоздалый ответ, даже не полный, но хорошее объяснение, ПОЧЕМУ я ненавижу этот шаблон, мнения и даже некоторые эмоции:

1) краткая версия: Active Record создает « тонкий слой » « сильной связи » между базой данных и кодом приложения. Которая не решает ни логических, ни каких бы то ни было проблем, вообще никаких проблем. IMHO он не предоставляет НИКАКОГО ЗНАЧЕНИЯ, кроме некоторого синтаксического сахара для программиста (который затем может использовать «синтаксис объекта» для доступа к некоторым данным, которые существуют в реляционной базе данных). Усилия по созданию некоторого комфорта для программистов должны (IMHO ...) лучше быть вложены в инструменты доступа к базам данных низкого уровня, например, некоторые варианты простых, легких, простых hash_map get_record( string id_value, string table_name, string id_column_name="id" )и подобных методов (конечно, концепции и элегантность сильно варьируются в зависимости от используемый язык).

2) длинная версия: в любых проектах, основанных на базе данных, где у меня был «концептуальный контроль», я избегал AR, и это было хорошо. Я обычно строю многоуровневую архитектуру (вы рано или поздно делите свое программное обеспечение на слои, по крайней мере, в проектах среднего и большого размера):

А1) сама база данных, таблицы, отношения, даже некоторая логика, если СУБД позволяет это (MySQL теперь тоже вырос)

A2) очень часто существует нечто большее, чем просто хранилище данных: файловая система (большие двоичные объекты в базе данных - не всегда хорошее решение ...), устаревшие системы (представьте себе, «как» они будут доступны, возможно множество разновидностей .. но это так. не суть ...)

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

C) уровень объектов приложения: «объекты приложения» иногда представляют собой простые строки таблицы в базе данных, но в большинстве случаев они в любом случае являются составными объектами, и к ним присоединена некоторая более высокая логика, поэтому вкладывать время в объекты AR на этом уровне просто бесполезно. , пустая трата драгоценного времени программистов, потому что «реальная ценность», «высшая логика» этих объектов должна быть реализована поверх объектов AR, в любом случае - с AR и без! И, например, зачем вам абстракция «Объекты записей журнала»? Код логики приложения записывает их, но должен ли он иметь возможность обновлять или удалять их? звучит глупо, и App::Log("I am a log message")его легче использовать, чемle=new LogEntry(); le.time=now(); le.text="I am a log message"; le.Insert();. И, например: использование «объекта записи журнала» в представлении журнала в вашем приложении будет работать для 100, 1000 или даже 10000 строк журнала, но рано или поздно вам придется оптимизировать - и я уверен, что в большинстве случаев вы просто используйте этот небольшой красивый оператор SQL SELECT в логике своего приложения (который полностью разрушает идею AR ...) вместо того, чтобы оборачивать этот небольшой оператор в жесткие фиксированные рамки идеи AR с большим количеством кода, обертывающего и скрывающего его. Время, которое вы потратили на написание и / или построение кода AR, можно было бы вложить в гораздо более умный интерфейс для чтения списков записей журнала (во многих случаях пределом нет). Программистам следует осмелиться изобретать новые абстракции, чтобы реализовать логику своего приложения, которая подходит для предполагаемого приложения, а не тупо повторно реализовывать глупые шаблоны.Звучит хорошо на первый взгляд!

D) логика приложения - реализует логику взаимодействия объектов и создания, удаления и перечисления (!) Объектов логики приложения (НЕТ, эти задачи редко должны быть привязаны к самим объектам логики приложения: говорит ли лист бумаги на вашем столе вы имена и расположение всех других листов в вашем офисе? Забудьте "статические" методы для перечисления объектов, это глупо, плохой компромисс, созданный для того, чтобы человеческий образ мышления вписался в [некоторые-не-все-AR-фреймворки -] AR мышление)

E) пользовательский интерфейс - ну, то, что я напишу в следующих строках, очень, очень, очень субъективно, но, по моему опыту, проекты, построенные на AR, часто игнорировали UI-часть приложения - время было потрачено на создание непонятных абстракций. . В конце концов, такие приложения тратят много времени кодировщиков и ощущаются как приложения от кодеров для кодеров, ориентированные на технические аспекты как внутри, так и снаружи. Кодировщики чувствуют себя хорошо (наконец-то тяжелая работа сделана, все закончено и правильно, в соответствии с концепцией на бумаге ...), а заказчики «просто должны понять, что так должно быть», потому что это «профессионально» .. окей извините, я отвлекся ;-)

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

В платных проектах я часто слышал требование начать с создания некоторых объектов «активной записи» в качестве строительного блока для логики приложения более высокого уровня. По моему опыту, это заметно частобыло своего рода оправданием того, что заказчик (в большинстве случаев компания, занимающаяся разработкой программного обеспечения) не имел хорошей концепции, широкого представления, представления о том, каким должен быть продукт. Эти клиенты мыслят в жестких рамках («в проекте десять лет назад он работал хорошо ...»), они могут конкретизировать сущности, они могут определять отношения сущностей, они могут разрушать отношения данных и определять базовую логику приложения, но затем они останавливаются и передайте его вам, и подумайте, что это все, что вам нужно ... им часто не хватает полной концепции логики приложения, пользовательского интерфейса, удобства использования и так далее, и так далее ... им не хватает широкого обзора и любви к подробности, и они хотят, чтобы вы следовали тому образу жизни AR, потому что ... ну, почему это сработало в этом проекте много лет назад, заставляет людей быть занятыми и молчать? Я не знаю. Но «подробности» отделите мужчин от мальчиков, или .. как был оригинальный рекламный слоган? ;-)

По прошествии многих лет (десять лет активного опыта разработки), всякий раз, когда заказчик упоминает «активную схему записи», у меня звонит сигнал тревоги. Я научился пытаться вернуть их к этой важной фазе зачатия , позволить им подумать дважды, попытаться показать свои концептуальные слабости или просто избегать их вообще, если они не различают (в конце концов, вы знаете, покупатель, который еще не знает, чего хочет, может даже думает, что знает, но не знает, или пытается бесплатно передать концептуальную работу МНЕ, стоит мне много драгоценных часов, дней, недель и месяцев моего времени, жить слишком мало ...).

Итак, наконец: ЭТО ВСЕ - вот почему я ненавижу этот глупый «шаблон активной записи», и я ненавижу и буду избегать его, когда это возможно.

РЕДАКТИРОВАТЬ : Я бы даже назвал это без шаблона. Это не решает никаких проблем (шаблоны не предназначены для создания синтаксического сахара). Это создает много проблем: корень всех его проблем (упомянутых во многих ответах здесь ..) заключается в том, что он просто скрывает старый добрый, хорошо разработанный и мощный SQL за интерфейсом, который по определению шаблонов чрезвычайно ограничен.

Этот шаблон заменяет гибкость синтаксическим сахаром!

Подумайте, какую проблему решает для вас AR?


1
Это архитектурный шаблон источника данных. Возможно, вам стоит прочитать «Паттерны архитектуры корпоративных приложений» Фаулера? У меня были аналогичные мысли до того, как я фактически использовал шаблон / ORM и обнаружил, насколько он упрощает вещи.
MattMcKnight,

1
Разделяю твои чувства. Я чувствую что-то неправильное, когда фреймворк не поддерживает составные ключи ... Я избегал любого вида ORM до SQLAlchemy, и мы часто используем его на более низком уровне, как генератор SQL. Он реализует Data Mapper и очень гибкий.
Marco Mariani,

1
Уже два дня я участвую в проекте, который использует "современную" ORM, возможно, реализации уже созрели (по сравнению с тем, с чем я работал несколько лет назад). Возможно, я передумаю, посмотрим через три месяца :-)
Frunsi

2
Проект готов, и знаете что? ORM все еще отстой, я потратил так много времени на проблемы сопоставления, которые легко выразить реляционным способом в связке «объектно-ориентированного кода». Ну, конечно, ORM предоставил способы выражать запросы в виде ООП + SQL-Mix - конечно, в синтаксисе, подобном ООП, - но это просто заняло больше времени, чем просто написание SQL-запроса. Утечка абстракции, «OOPSQLExperiment» поверх ООП - позволить пользователям писать SQL в синтаксисе ООП была худшей идеей на свете. Нет, больше никогда.
Фрунси

1
Я писал чистый SQL для всего на протяжении многих лет. Rails AR иногда меня расстраивает, и в отношении пассивных запросов я почти согласен с вами, но вот что он решает: 1) Делает достаточно сложным сохранение данных, которые не прошли проверку. 2) Отслеживание того, что изменилось в памяти с момента последнего сохранения. 3) Использование пункта 2 для написания разумных before_saveобратных вызовов для поддержания согласованности в записи 4) after_commitхуки для триггеров внешней службы. 5) Хороший DSL для организации изменений DDL в ревизии (миграции). (Боль все еще есть, но отсутствие шаблона хуже, когда> 1 разработчик.)
Adamantish

6

Некоторые сообщения сбивают меня с толку. Некоторые ответы относятся к «ORM» против «SQL» или что-то в этом роде.

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

Эти объекты обычно имеют бизнес-атрибуты (свойства bean-компонента) и некоторое поведение (методы, которые обычно работают с этими свойствами).

AR просто говорит «добавить несколько методов к этим объектам домена» для задач, связанных с базой данных.

И я должен сказать, исходя из моего мнения и опыта, что мне не нравится этот узор.

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

Для меня настоящая проблема связана только с ООП. Шаблон AR заставляет вас каким-то образом добавить зависимость от вашего объекта к объектам инфраструктуры. Эти объекты инфраструктуры позволяют объекту домена запрашивать базу данных с помощью методов, предложенных AR.

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

Реализация AR в Spring Roo интересна тем, что не полагается на сам объект, а на некоторые файлы AspectJ. Но если позже вы не захотите работать с Roo и вам придется реорганизовать проект, методы AR будут реализованы непосредственно в объектах вашего домена.

Другая точка зрения. Представьте, что мы не используем реляционную базу данных для хранения наших объектов. Представьте, что приложение хранит объекты нашего домена, например, в базе данных NoSQL или просто в файлах XML. Будем ли мы реализовывать методы, выполняющие эти задачи, в наших объектах домена? Я так не думаю (например, в случае с XM мы добавили бы зависимости, связанные с XML, к нашим объектам домена ... Мне действительно грустно). Почему же тогда мы должны реализовывать методы реляционной БД в объектах предметной области, как говорит шаблон Ar?

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


Добро пожаловать в SO. Оценил ваш комментарий, но этот вопрос был закрыт как неконструктивный NullUserException 17 декабря 2011 в 1:17
Тони Рэд

3

Вопрос в шаблоне проектирования Active Record. Не инструмент orm.

Исходный вопрос помечен рельсами и относится к Twitter, который построен на Ruby on Rails. Фреймворк ActiveRecord в Rails - это реализация шаблона проектирования Active Record Фаулера.


2

Главное, что я видел в отношении жалоб на Active Record, - это то, что когда вы создаете модель вокруг стола и выбираете несколько экземпляров модели, вы в основном выполняете «select * from ...». Это нормально для редактирования записи или отображения записи, но если вы хотите, скажем, отобразить список городов для всех контактов в вашей базе данных, вы можете сделать «выберите город из ...» и получить только города . Для этого с Active Record потребуется выбрать все столбцы, но только с помощью City.

Конечно, разные реализации будут обрабатывать это по-разному. Тем не менее, это одна проблема.

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

Я копаю Active Record. :-)

HTH


2
«Выполнение этого с Active Record потребует, чтобы вы выбрали все столбцы, но только с помощью City». На самом деле указать предложение select чрезвычайно просто.
MattMcKnight

1

Мне нравится, как SubSonic делает только одну колонку.
Либо

DataBaseTable.GetList(DataBaseTable.Columns.ColumnYouWant)

, или:

Query q = DataBaseTable.CreateQuery()
               .WHERE(DataBaseTable.Columns.ColumnToFilterOn,value);
q.SelectList = DataBaseTable.Columns.ColumnYouWant;
q.Load();

Но Linq по-прежнему король, когда дело доходит до отложенной загрузки.


1

@BlaM: Иногда я просто реализовывал активную запись для результата соединения. Не всегда должно быть отношение Таблица <--> Active Record. Почему не «Результат оператора соединения» <--> Active Record?


1

Я собираюсь говорить об Active Record как об шаблоне проектирования, я не видел ROR.

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

Во-вторых, объекты домена в Active Record имеют тенденцию быть 1 к 1 с базой данных, что может считаться ограничением в некоторых системах (в основном n-уровневых).

Это просто абстрактные вещи, я не видел реальной реализации этого паттерна в Ruby on Rails.


0

Проблема, которую я вижу с Active Records, заключается в том, что это всегда примерно один таблица. Это нормально, если вы действительно работаете только с одной таблицей, но когда вы работаете с данными, в большинстве случаев у вас будет какое-то соединение.

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


@BlaM: Вы абсолютно правы. Хотя я никогда не использовал Active Record, я использовал другие ORM-системы (особенно NHibernate), и у меня есть две большие претензии: глупые способы создания объектов (например, файлов .hbm.xml, каждый из которых получает скомпилированы в свою собственную сборку), а снижение производительности вызвано простой загрузкой объектов (NHibernate может на несколько секунд активировать одноядерный процесс, выполняя запрос, который вообще ничего не загружает, когда эквивалентный запрос SQL почти не обрабатывается). Конечно, это не относится к Active Record, но я считаю, что большинство ORM-систем (и ORM-подобных систем) похоже
TheSmurf

Есть много альтернатив использованию файлов hbm.xml. См., Например, NHibernate.Mapping.Attributes и fluent-nhibernate.
Маурисио Схеффер,

Что касается производительности создания объектов, я никогда не сталкивался с такими проблемами производительности, вы можете проверить с помощью профилировщика.
Маурисио Схеффер,

@mausch: Профилировщик не нужен. Это довольно известная проблема. Не знаю, применимо ли это к последней версии (которую я пока не использую на работе). ayende.com/Blog/archive/2007/10/26/…
TheSmurf

4
Использование: joins или: includes в находках IE Customer.find (: all,: include =>: contacts,: conditions => "active = 1") выполнит соединение SQL, а не полное сканирование таблицы.
Tilendor

0

Проблема с ActiveRecord заключается в том, что автоматически генерируемые запросы могут вызвать проблемы с производительностью.

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


0

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


ActiveRecord фактически решает проблему несоответствия импеданса, позволяя вам кодировать объектно-ориентированный код в соответствии с реляционной схемой.
Маурисио Схеффер,

Хотите уточнить? По общему мнению, объекты, смоделированные на основе реляционной базы данных, по определению не являются объектно-ориентированными (поскольку реляционные базы данных не связаны с объектно-ориентированными концепциями, такими как наследование и полиморфизм).
Кевин Панг,

Есть три известных способа сопоставить наследование с реляционной схемой. Ссылка: castleproject.org/ActiveRecord/documentation/trunk/usersguide/…
Маурисио Шеффер,

Я думаю, вы ошибочно принимаете проект Castle Active Record OSS за Active Record за шаблон проектирования. Исходный вопрос (и мой ответ) относятся к шаблону проектирования. В проект Castle Active Record встроены вещи, помогающие в OO-разработке, но сам паттерн - нет.
Кевин Панг,

Я просто цитировал Касла как ссылку. ActiveRecord от RoR реализует наследование только одной таблицы ( martinfowler.com/eaaCatalog/singleTableInheritance.html ), но другие стратегии рассматриваются ( blog.zerosum.org/2007/2/16/… )
Маурисио Шеффер

0

Попробуйте установить полиморфные отношения «многие ко многим». Не так просто. Особенно, если вы не употребляете ИППП.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.