Por que todo o Active Record odeia? [fechadas]


103

À medida que aprendo mais e mais sobre OOP e começo a implementar vários padrões de projeto, continuo voltando aos casos em que as pessoas odeiam o Active Record .

Freqüentemente, as pessoas dizem que ele não é bem escalável (citando o Twitter como seu principal exemplo) - mas ninguém realmente explica por que ele não se dimensiona bem; e / ou como alcançar os prós da RA sem os contras (por meio de um padrão semelhante, mas diferente?)

Espero que isso não se transforme em uma guerra santa sobre padrões de design - tudo que eu quero saber é **** especificamente **** o que há de errado com o Active Record.

Se não escalar bem, por que não?

Que outros problemas isso tem?


9
Acho que, em geral, muito ódio e antipatia pelos padrões de design estão relacionados ao uso incorreto. As pessoas tendem a abusar e usá-los no contexto errado e acabam com uma solução mais complexa do que o original
terjetyl

1
A implementação do Active Record do Ruby é mais parecida com um ORM.
Jimmy T.

1
Existe um fenômeno social que é para obter apreciação, mais reconhecimento, parecer mais inteligente e cortante, as pessoas tendem a repetir mecanicamente qualquer exagero de negação de qualquer padrão atual, modelo, tecnologias amplamente adotadas, confundindo-o com o progresso revolucionário para a próxima onda.
Andre Figueiredo

Respostas:


90

ActiveRecord the Design Pattern e ActiveRecord the Rails ORM Library , e também há uma tonelada de cópias para .NET e outras linguagens.

Todas essas são coisas diferentes. Eles geralmente seguem esse padrão de design, mas o estendem e modificam de muitas maneiras diferentes, portanto, antes que alguém diga "ActiveRecord é uma merda", ele precisa ser qualificado dizendo "qual ActiveRecord há montes?"

Só estou familiarizado com o ActiveRecord do Rails, vou tentar resolver todas as reclamações que foram levantadas no contexto de usá-lo.

@BlaM

O problema que vejo com Active Records é que é sempre sobre uma tabela

Código:

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

Isso gera SQL com LEFT JOIN companies on companies.id = person.company_ide gera automaticamente objetos da empresa associados para que você possa fazer people.first.companye não precise acessar o banco de dados porque os dados já estão presentes.

@ pix0r

O problema inerente ao Active Record é que as consultas ao banco de dados são geradas e executadas automaticamente para preencher objetos e modificar os registros do banco de dados

Código:

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

Isso é desencorajado porque é feio, mas para os casos em que você simplesmente precisa escrever SQL bruto, isso é feito facilmente.

@Tim Sullivan

... e você seleciona várias instâncias do modelo, basicamente está fazendo um "selecionar * de ..."

Código:

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

Isso selecionará apenas as colunas de nome e ID do banco de dados, todos os outros 'atributos' nos objetos mapeados serão apenas nulos, a menos que você recarregue manualmente esse objeto e assim por diante.


Poderoso! Eu não sabia sobre esse recurso específico. Mais um argumento pró-AR para eu colocar em meu arsenal.
Tim Sullivan

A adesão vai além do padrão Active Record.
Jimmy T.

"Person.find_by_sql" não é um padrão Active Record. Seu praticamente "registro ativo" falhou comigo, então eu preciso corrigi-lo manualmente.
Magallanes

52

Sempre achei que ActiveRecord é bom para aplicativos baseados em CRUD rápidos, onde o modelo é relativamente plano (como em, não muitas hierarquias de classes). No entanto, para aplicativos com hierarquias OO complexas, um DataMapper é provavelmente uma solução melhor. Enquanto ActiveRecord assume uma proporção de 1: 1 entre suas tabelas e seus objetos de dados, esse tipo de relacionamento se torna difícil com domínios mais complexos. Em seu livro sobre padrões , Martin Fowler aponta que ActiveRecord tende a quebrar sob condições em que seu modelo é bastante complexo, e sugere um DataMapper como alternativa.

Descobri que isso é verdade na prática. Nos casos em que você tem muita herança em seu domínio, é mais difícil mapear a herança para seu RDBMS do que mapear associações ou composição.

A forma como eu faço isso é ter objetos de "domínio" que são acessados ​​por seus controladores através dessas classes DataMapper (ou "camada de serviço"). Eles não refletem diretamente o banco de dados, mas atuam como sua representação OO para algum objeto do mundo real. Digamos que você tenha uma classe User em seu domínio e precise ter referências a, ou coleções de outros objetos, já carregados quando você recuperar esse objeto User. Os dados podem vir de muitas tabelas diferentes e um padrão ActiveRecord pode tornar isso muito difícil.

Em vez de carregar o objeto User diretamente e acessar dados usando uma API de estilo ActiveRecord, seu código de controlador recupera um objeto User chamando a API do método UserMapper.getUser (), por exemplo. É esse mapeador que é responsável por carregar quaisquer objetos associados de suas respectivas tabelas e retornar o objeto "domínio" do Usuário completo para o chamador.

Essencialmente, você está apenas adicionando outra camada de abstração para tornar o código mais gerenciável. Se suas classes DataMapper contêm SQL customizado bruto ou chamadas para uma API da camada de abstração de dados, ou mesmo acessam um padrão ActiveRecord, não importa realmente para o código do controlador que está recebendo um objeto User bonito e populado.

Enfim, é assim que eu faço.


5
Parece que você simplesmente não está familiarizado com o ActiveRecord. "ActiveRecord assume uma proporção de 1: 1 entre suas tabelas". Simplesmente não é verdade. ActiveRecord tem todos os tipos de magia relacional incrível. Veja api.rubyonrails.org/classes/ActiveRecord/Associations/…
tybro0103

16
@ JoãoBragança - talvez ao invés de um comentário sarcástico, você poderia explicar as dificuldades que ocorrem quando os dados de alguém são fragmentados - para que o resto de nós possa aprender alguma coisa :)
Taryn East

11

Acho que há provavelmente um conjunto de razões muito diferente entre o motivo pelo qual as pessoas estão "odiando" o ActiveRecord e o que está "errado" com ele.

Sobre a questão do ódio, há muito veneno em relação a qualquer coisa relacionada a Rails. Quanto ao que há de errado com ela, é provável que seja como toda tecnologia e haja situações em que é uma boa escolha e situações em que há melhores escolhas. A situação em que você não consegue tirar proveito da maioria dos recursos do Rails ActiveRecord, na minha experiência, é onde o banco de dados está mal estruturado. Se você estiver acessando dados sem chaves primárias, com coisas que violam a primeira forma normal, onde existem muitos procedimentos armazenados necessários para acessar os dados, é melhor usar algo que seja mais como um invólucro SQL. Se o seu banco de dados for relativamente bem estruturado, ActiveRecord permite que você aproveite isso.

Para adicionar ao tema de responder aos comentadores que dizem que as coisas estão difíceis no ActiveRecord com uma réplica de trecho de código

@Sam McAfee Digamos que você tenha uma classe de usuário em seu domínio e precise ter referências ou coleções de outros objetos já carregadas quando você recuperar esse objeto de usuário. Os dados podem vir de muitas tabelas diferentes e um padrão ActiveRecord pode tornar isso muito difícil.

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

Ao usar a opção de inclusão, ActiveRecord permite que você substitua o comportamento de carregamento lento padrão.


8

Minha resposta longa e tardia, nem mesmo completa, mas uma boa explicação POR QUE odeio esse padrão, opiniões e até algumas emoções:

1) versão resumida: Active Record cria uma " camada fina " de " ligação forte " entre o banco de dados e o código do aplicativo. O que não resolve nenhum problema lógico, nenhum problema, nenhum problema. IMHO ele não fornece NENHUM VALOR, exceto algum açúcar sintático para o programador (que pode então usar uma "sintaxe de objeto" para acessar alguns dados, que existem em um banco de dados relacional). O esforço para criar algum conforto para os programadores deve (IMHO ...) melhor ser investido em ferramentas de acesso a banco de dados de baixo nível, por exemplo, algumas variações de simples, fácil, simpleshash_map get_record( string id_value, string table_name, string id_column_name="id" ) métodos e semelhantes (é claro, os conceitos e elegância variam muito com o linguagem utilizada).

2) versão longa: em qualquer projeto baseado em banco de dados onde eu tivesse o "controle conceitual" das coisas, evitei o RA, e isso era bom. Eu geralmente construo uma arquitetura em camadas (mais cedo ou mais tarde você divide seu software em camadas, pelo menos em projetos de médio a grande porte):

A1) o próprio banco de dados, tabelas, relações, até mesmo alguma lógica se o SGBD permitir (o MySQL também está crescido agora)

A2) muitas vezes, há mais do que um armazenamento de dados: sistema de arquivos (blobs no banco de dados nem sempre são uma boa decisão ...), sistemas legados (imagine "como" eles serão acessados, muitas variedades possíveis .. mas isso é não é o ponto ...)

B) camada de acesso ao banco de dados (neste nível, métodos de ferramentas, auxiliares para acessar facilmente os dados no banco de dados são muito bem-vindos, mas AR não fornece nenhum valor aqui, exceto algum açúcar sintático)

C) camada de objetos de aplicativo: "objetos de aplicativo" às vezes são linhas simples de uma tabela no banco de dados, mas na maioria das vezes são objetos compostos de qualquer maneira, e têm alguma lógica superior anexada, então investir tempo em objetos AR neste nível é simplesmente inútil , uma perda de tempo precioso dos codificadores, porque o "valor real", a "lógica superior" desses objetos precisa ser implementada em cima dos objetos AR, de qualquer maneira - com e sem AR! E, por exemplo, por que você deseja ter uma abstração de "Objetos de entrada de log"? O código lógico do aplicativo os grava, mas deve ter a capacidade de atualizá-los ou excluí-los? parece bobo, e App::Log("I am a log message")algumas magnitudes são mais fáceis de usar do quele=new LogEntry(); le.time=now(); le.text="I am a log message"; le.Insert();. E por exemplo: usar um "objeto de entrada de registro" na visualização de registro em seu aplicativo funcionará para 100, 1000 ou mesmo 10.000 linhas de registro, mas mais cedo ou mais tarde você terá que otimizar - e aposto que na maioria dos casos, você apenas use aquela pequena e bonita instrução SQL SELECT na lógica do seu aplicativo (que quebra totalmente a ideia de AR ...), em vez de embrulhar essa pequena instrução em rígidos quadros de ideias de AR fixos com muito código embrulhando e escondendo-o. O tempo que você perdeu escrevendo e / ou construindo código AR poderia ter sido investido em uma interface muito mais inteligente para ler listas de entradas de log (de muitas maneiras, o céu é o limite). Os codificadores devem ousar inventar novas abstrações para realizar a lógica de sua aplicação que se encaixe na aplicação pretendida e não reimplementar estupidamente padrões bobos, que pareça bom à primeira vista!

D) a lógica do aplicativo - implementa a lógica de objetos de interação e criação, exclusão e listagem (!) De objetos lógicos do aplicativo (NÃO, essas tarefas raramente devem ser ancoradas nos próprios objetos lógicos do aplicativo: a folha de papel em sua mesa diz você os nomes e localizações de todas as outras planilhas em seu escritório? esqueça os métodos "estáticos" para listar objetos, isso é bobo, um mau compromisso criado para fazer a maneira humana de pensar se encaixar em [alguns-não-todos-AR-framework-like -] AR pensando)

E) a interface do usuário - bem, o que vou escrever nas linhas a seguir é muito, muito, muito subjetivo, mas, na minha experiência, os projetos que se baseiam em AR muitas vezes negligenciam a parte da interface do usuário de um aplicativo - tempo foi perdido na criação de abstrações obscuras . No final, tais aplicativos desperdiçaram muito tempo dos programadores e parecem aplicativos de programadores para programadores, inclinados à tecnologia por dentro e por fora. Os codificadores se sentem bem (trabalho duro enfim feito, tudo acabado e correto, de acordo com o conceito no papel ...), e os clientes "só tem que aprender que precisa ser assim", porque isso é "profissional" .. ok, desculpe, estou divagando ;-)

Bem, admito que tudo isso é subjetivo, mas é minha experiência (Ruby on Rails excluído, pode ser diferente, e eu não tenho nenhuma experiência prática com essa abordagem).

Em projetos pagos, muitas vezes ouvi a demanda para começar com a criação de alguns objetos de "registro ativo" como um bloco de construção para a lógica de aplicativo de nível superior. Na minha experiência, com frequênciaera uma espécie de desculpa para o cliente (uma empresa de desenvolvimento de software na maioria dos casos) não ter um bom conceito, uma visão ampla, uma visão geral do que o produto deveria ser. Esses clientes pensam em quadros rígidos ("no projeto há dez anos funcionava bem ..."), eles podem dar corpo a entidades, podem definir relações de entidades, podem quebrar relações de dados e definir lógicas básicas de aplicação, mas então param e entregá-lo a você, e acho que isso é tudo de que você precisa ... muitas vezes falta-lhes um conceito completo de lógica de aplicativo, interface de usuário, usabilidade e assim por diante ... eles não têm a visão ampla e não gostam do detalhes, e eles querem que você siga aquele jeito de RA das coisas, porque ... bem, por que funcionou naquele projeto anos atrás, mantém as pessoas ocupadas e em silêncio? Eu não sei. Mas os "detalhes" separar os homens dos meninos, ou ... como era o slogan do anúncio original? ;-)

Depois de muitos anos (dez anos de experiência em desenvolvimento ativo), sempre que um cliente menciona um "padrão de registro ativo", meu alarme toca. Eu aprendi a tentar levá-los de volta à fase essencial da concepção , deixá-los pensar duas vezes, tentar mostrar suas fraquezas conceituais ou simplesmente evitá-los se eles não forem discernentes (no final, você sabe, um cliente que ainda não sabe sabe o que quer, talvez até pense que sabe, mas não sabe, ou tenta externalizar o conceito de trabalho para MIM de graça, me custa muitas horas, dias, semanas e meses preciosos do meu tempo, a vida é muito curta ...).

Então, finalmente: ISTO é porque eu odeio aquele "padrão de registro ativo" idiota, e eu odeio e evitarei isso sempre que possível.

EDIT : Eu até chamaria isso de No-Pattern. Não resolve nenhum problema (os padrões não têm como objetivo criar açúcar sintático). Isso cria muitos problemas: a raiz de todos os seus problemas (mencionados em muitas respostas aqui ..) é que ele apenas esconde o bom e velho SQL bem desenvolvido e poderoso por trás de uma interface que é pela definição de padrões extremamente limitada.

Este padrão substitui a flexibilidade por açúcar sintático!

Pense nisso, qual problema o RA resolve para você?


1
É um padrão de arquitetura de fonte de dados. Talvez você deva ler Patterns of Enterprise Application Architecture, de Fowler? Eu tinha pensamentos semelhantes aos seus antes de realmente usar o padrão / ORM e descobrir o quanto ele simplificava as coisas.
MattMcKnight

1
Eu compartilho seus sentimentos. Sinto algo errado quando um framework não oferece suporte a chaves compostas ... Evitei qualquer tipo de ORM antes do SQLAlchemy e geralmente o usamos em um nível inferior, como um gerador de SQL. Ele implementa Data Mapper e é muito flexível.
Marco Mariani

1
Há dois dias estou envolvido em um projeto que usa ORM "state-of-the-art", talvez as implementações estejam amadurecidas agora (em comparação ao que trabalhei alguns anos atrás). Talvez, minha mente mude, veremos em três meses :-)
Frunsi

2
O projeto está feito, e quer saber? ORM ainda é uma merda, eu perdi muito tempo com problemas de mapeamento que são facilmente expressos de uma forma relacional para um monte de "código orientado a objetos". Bem, é claro que o ORM forneceu maneiras de expressar consultas em uma espécie de OOP + SQL-Mix - claro, em uma sintaxe semelhante a OOP - mas isso levou mais tempo do que simplesmente escrever uma consulta SQL. A abstração vazou, o "OOPSQLExperiment" em cima do OOP - permitir que os usuários escrevam SQL na sintaxe OOP foi a pior ideia de todos os tempos. Não, nunca mais.
Frunsi de

1
Escrevi SQL bruto para tudo por muitos anos. Rails AR me frustra às vezes e para consultas passivas eu quase concordo com você, mas isso é o que ele resolve: 1) Torna apropriadamente difícil salvar dados que falham na validação. 2) Rastrear o que mudou na memória desde a última persistência. 3) Usando o ponto 2 para escrever before_saveretornos de chamada sensíveis para manter a consistência no registro 4) after_commitganchos para acionadores de serviço externo. 5) Um bom DSL para organizar mudanças DDL em changesets (migrações). (Ainda há dor lá, mas não há padrão é pior quando> 1 desenvolvedor.)
Adamantish,

6

Algumas mensagens estão me deixando confuso. Algumas respostas vão para "ORM" vs "SQL" ou algo parecido.

O fato é que AR é apenas um padrão de programação de simplificação, onde você tira proveito de seus objetos de domínio para escrever o código de acesso ao banco de dados.

Esses objetos geralmente têm atributos de negócios (propriedades do bean) e alguns comportamentos (métodos que geralmente funcionam nessas propriedades).

O AR apenas diz "adicione alguns métodos a esses objetos de domínio" para tarefas relacionadas ao banco de dados.

E devo dizer, pela minha opinião e experiência, que não gosto do padrão.

À primeira vista, pode parecer muito bom. Algumas ferramentas Java modernas, como Spring Roo, usam esse padrão.

Para mim, o verdadeiro problema é apenas com a preocupação OOP. O padrão AR força você de alguma forma a adicionar uma dependência de seu objeto aos objetos de infraestrutura. Esses objetos de infra-estrutura permitem ao objeto de domínio consultar a base de dados através dos métodos sugeridos pela AR.

Sempre disse que duas camadas são a chave para o sucesso de um projeto. A camada de serviço (onde reside a lógica do negócio ou pode ser exportada por meio de algum tipo de tecnologia de remoting, como Web Services, por exemplo) e a camada de domínio. Na minha opinião, se adicionarmos algumas dependências (não realmente necessárias) aos objetos da camada de domínio para resolver o padrão AR, nossos objetos de domínio serão mais difíceis de compartilhar com outras camadas ou (raros) aplicativos externos.

A implementação de AR do Spring Roo é interessante, porque não depende do objeto em si, mas de alguns arquivos AspectJ. Mas se mais tarde você não quiser trabalhar com o Roo e precisar refatorar o projeto, os métodos AR serão implementados diretamente nos seus objetos de domínio.

Outro ponto de vista. Imagine que não usamos um banco de dados relacional para armazenar nossos objetos. Imagine que a aplicação armazene nossos objetos de domínio em um Banco de Dados NoSQL ou apenas em arquivos XML, por exemplo. Implementaríamos os métodos que realizam essas tarefas em nossos objetos de domínio? Acho que não (por exemplo, no caso do XM, adicionaríamos dependências relacionadas a XML aos nossos objetos de domínio ... Realmente triste, eu acho). Por que então temos que implementar os métodos de banco de dados relacionais nos objetos de domínio, como diz o padrão Ar?

Resumindo, o padrão AR pode parecer mais simples e bom para aplicações pequenas e simples. Mas, quando temos aplicativos complexos e grandes, acho que a arquitetura clássica em camadas é uma abordagem melhor.


Bem-vindo ao SO. Agradecemos seu comentário, mas esta questão foi encerrada como não construtiva por NullUserException em 17 de dezembro de 2011 às 1:17
Tony Rad

3

A questão é sobre o padrão de design do Active Record. Não é uma ferramenta orm.

A pergunta original está marcada com rails e se refere ao Twitter, que é construído em Ruby on Rails. O framework ActiveRecord dentro do Rails é uma implementação do padrão de projeto Active Record de Fowler.


2

A principal coisa que vi com relação às reclamações sobre o Active Record é que quando você cria um modelo em torno de uma mesa e seleciona várias instâncias do modelo, basicamente está fazendo um "selecionar * de ...". Isso é bom para editar um registro ou exibir um registro, mas se você quiser, digamos, exibir uma lista das cidades para todos os contatos em seu banco de dados, você pode "selecionar cidade de ..." e obter apenas as cidades . Fazer isso com o Active Record exigiria que você selecione todas as colunas, mas apenas usando City.

Claro, várias implementações irão lidar com isso de forma diferente. No entanto, é um problema.

Agora, você pode contornar isso criando um novo modelo para a coisa específica que você está tentando fazer, mas algumas pessoas argumentariam que é mais esforço do que benefício.

Eu, eu curto o Active Record. :-)

HTH


2
"Fazer isso com o Active Record exigiria que você selecione todas as colunas, mas apenas usando City." Na verdade, é extremamente fácil especificar uma cláusula select.
MattMcKnight

1

Adoro a forma como o SubSonic faz apenas uma coluna.
Ou

DataBaseTable.GetList(DataBaseTable.Columns.ColumnYouWant)

, ou:

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

Mas Linq ainda é rei quando se trata de carregamento preguiçoso.


1

@BlaM: Às vezes, acabei de implementar um registro ativo para o resultado de uma junção. Nem sempre tem que ser a relação Tabela <--> Active Record. Por que não "Result of a Join statement" <--> Active Record?


1

Vou falar sobre Active Record como padrão de design, não vi ROR.

Alguns desenvolvedores odeiam o Active Record, porque lêem livros inteligentes sobre como escrever código limpo e organizado, e esses livros afirmam que o registro ativo viola o princípio de responsabilidade único, viola a regra DDD de que o objeto de domínio deve ser persistente ignorante e muitas outras regras desse tipo de livro .

A segunda coisa que os objetos de domínio no Active Record tendem a ser 1 para 1 com o banco de dados, o que pode ser considerado uma limitação em alguns tipos de sistemas (principalmente n-tier).

Isso é apenas coisas abstratas, eu não vi a implementação real deste padrão do Ruby on Rails.


0

O problema que vejo com Active Records é que sempre se trata de apenas uma tabela. Tudo bem, contanto que você realmente trabalhe apenas com aquela tabela, mas quando você trabalha com dados na maioria dos casos, você terá algum tipo de junção em algum lugar.

Sim, a junção geralmente é pior do que nenhuma junção quando se trata de desempenho, mas a junção geralmente é melhor do que a junção "falsa" , primeiro lendo toda a tabela A e, em seguida, usando as informações obtidas para ler e filtrar a tabela B.


@BlaM: Você está absolutamente certo. Embora eu nunca tenha usado o Active Record, usei outros sistemas ORM integrados (particularmente NHibernate), e há duas grandes reclamações que tenho: maneiras tolas de criar objetos (ou seja, arquivos .hbm.xml, cada um dos quais é compilado em seu próprio assembly) e o impacto de desempenho incorrido apenas ao carregar objetos (NHibernate pode aumentar um proc de núcleo único por vários segundos, executando uma consulta que não carrega nada, quando uma consulta SQL equivalente quase não leva processamento). Não é específico do Active Record, é claro, mas acho que a maioria dos sistemas ORM (e sistemas semelhantes a ORM) parecem
TheSmurf

Existem muitas alternativas ao uso de arquivos hbm.xml. Veja, por exemplo, NHibernate.Mapping.Attributes e fluent-nhibernate.
Mauricio Scheffer

Sobre o desempenho de criação de objetos, eu nunca tive problemas de desempenho, você pode querer verificar com um criador de perfil.
Mauricio Scheffer

@mausch: Não precisa de um profiler. É um problema bastante conhecido. Não sei se se aplica à versão mais recente (que ainda não estou usando no meu trabalho). ayende.com/Blog/archive/2007/10/26/…
TheSmurf

4
Usar: joins ou: includes no achado IE Customer.find (: all,: include =>: contacts,: conditions => "active = 1") fará uma junção SQL, não uma varredura completa da tabela.
Tilendor

0

O problema com o ActiveRecord é que as consultas que ele gera automaticamente para você podem causar problemas de desempenho.

Você acaba fazendo alguns truques não intuitivos para otimizar as consultas que o deixam se perguntando se teria sido mais eficaz escrever a consulta à mão em primeiro lugar.


0

Embora todos os outros comentários sobre a otimização de SQL sejam certamente válidos, minha principal reclamação com o padrão de registro ativo é que geralmente leva a incompatibilidade de impedância . Gosto de manter meu domínio limpo e devidamente encapsulado, o que o padrão de registro ativo geralmente destrói toda esperança de fazer.


O ActiveRecord realmente resolve o problema de incompatibilidade de impedância, permitindo que você codifique de forma OO em relação a um esquema relacional.
Mauricio Scheffer

Cuidado ao elaborar? O consenso geral é que os objetos modelados após um banco de dados relacional são, por definição, não orientados a objetos (uma vez que os bancos de dados relacionais não giram em torno de conceitos OO, como herança e polimorfismo).
Kevin Pang

Existem três maneiras conhecidas de mapear a herança para um esquema relacional. Ref: castleproject.org/ActiveRecord/documentation/trunk/usersguide/…
Mauricio Scheffer

Acho que você está confundindo o projeto Castle Active Record OSS com o Active Record, o padrão de design. A pergunta original (e minha resposta) referem-se ao padrão de design. O projeto Castle Active Record tem coisas embutidas nele para ajudar no desenvolvimento OO, mas o próprio padrão não.
Kevin Pang

Eu estava apenas citando Castle como referência. O ActiveRecord do RoR implementa herança de tabela única apenas ( martinfowler.com/eaaCatalog/singleTableInheritance.html ), mas as outras estratégias estão sendo consideradas ( blog.zerosum.org/2007/2/16/… )
Mauricio Scheffer

0

Tente fazer um relacionamento polimórfico de muitos para muitos. Não tão fácil. Especialmente quando você não está usando o STI.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.