¿Por qué todo el odio de Active Record? [cerrado]

103

A medida que aprendo más y más sobre la programación orientada a objetos y comienzo a implementar varios patrones de diseño, sigo volviendo a los casos en los que la gente odia en Active Record .

A menudo, la gente dice que no escala bien (citando a Twitter como su mejor ejemplo), pero nadie explica realmente por qué no escala bien; y / o cómo lograr los pros de AR sin los contras (¿a través de un patrón similar pero diferente?)

Con suerte, esto no se convertirá en una guerra santa sobre los patrones de diseño; todo lo que quiero saber es saber qué pasa con Active Record.

Si no escala bien, ¿por qué no?

¿Qué otros problemas tiene?

Adam Tuttle
fuente
9
Supongo que, en general, mucho odio y aversión contra los patrones de diseño están relacionados con el uso incorrecto. La gente tiende a abusar y usarlos en un contexto equivocado y terminar con una solución más compleja que el original
terjetyl
1
La implementación de Active Record de Ruby es más como un ORM.
Jimmy T.
1
Hay un fenómeno social que es para obtener apreciación, más reconocimiento, parecer más inteligente y cortante, la gente tiende a repetir mecánicamente cualquier exageración de negación de cualquier estándar actual, modelo, tecnología ampliamente adoptada, confundiéndolo con el progreso revolucionario a la próxima ola.
Andre Figueiredo

Respuestas:

90

Existe ActiveRecord the Design Pattern y ActiveRecord the Rails ORM Library , y también hay un montón de imitaciones para .NET y otros lenguajes.

Todas estas son cosas diferentes. En su mayoría siguen ese patrón de diseño, pero lo amplían y modifican de muchas maneras diferentes, por lo que antes de que alguien diga "ActiveRecord apesta", debe calificarse diciendo "¿qué ActiveRecord, hay montones?"

Solo estoy familiarizado con ActiveRecord de Rails, intentaré abordar todas las quejas que se han presentado en el contexto de su uso.

@BlaM

El problema que veo con Active Records es que siempre se trata de una sola tabla

Código:

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

Esto genera SQL con LEFT JOIN companies on companies.id = person.company_idy genera automáticamente los objetos de la Compañía asociados para que pueda hacerlo people.first.companyy no necesita ingresar a la base de datos porque los datos ya están presentes.

@ pix0r

El problema inherente con Active Record es que las consultas de la base de datos se generan y ejecutan automáticamente para completar objetos y modificar los registros de la base de datos

Código:

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

Esto se desaconseja porque es feo, pero para los casos en los que simplemente necesita escribir SQL sin formato, es fácil de hacer.

@Tim Sullivan

... y selecciona varias instancias del modelo, básicamente está haciendo un "seleccionar * de ..."

Código:

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

Esto solo seleccionará las columnas de nombre e ID de la base de datos, todos los demás 'atributos' en los objetos mapeados serán nulos, a menos que recargue manualmente ese objeto, y así sucesivamente.

Orion Edwards
fuente
¡Poderoso! No conocía esa característica específica. Otro argumento más a favor de la RA para que lo ponga en mi arsenal.
Tim Sullivan
Unirse va más allá del patrón Active Record.
Jimmy T.
"Person.find_by_sql" no es un patrón de registro activo en absoluto. Su "registro activo" me falló, así que necesito parchearlo manualmente.
magallanes
52

Siempre he encontrado que ActiveRecord es bueno para aplicaciones rápidas basadas en CRUD donde el modelo es relativamente plano (como en, no muchas jerarquías de clases). Sin embargo, para aplicaciones con jerarquías OO complejas, un DataMapper es probablemente una mejor solución. Si bien ActiveRecord asume una proporción de 1: 1 entre sus tablas y sus objetos de datos, ese tipo de relación se vuelve difícil de manejar con dominios más complejos. En su libro sobre patrones , Martin Fowler señala que ActiveRecord tiende a fallar en condiciones en las que su modelo es bastante complejo y sugiere un DataMapper como alternativa.

He descubierto que esto es cierto en la práctica. En los casos en los que tiene mucha herencia en su dominio, es más difícil asignar la herencia a su RDBMS que asignar asociaciones o composición.

La forma en que lo hago es tener objetos de "dominio" a los que acceden sus controladores a través de estas clases de DataMapper (o "capa de servicio"). Estos no reflejan directamente la base de datos, sino que actúan como su representación OO para algún objeto del mundo real. Supongamos que tiene una clase de usuario en su dominio y necesita tener referencias o colecciones de otros objetos ya cargados cuando recupera ese objeto de usuario. Los datos pueden provenir de muchas tablas diferentes y un patrón de ActiveRecord puede hacer que sea realmente difícil.

En lugar de cargar el objeto Usuario directamente y acceder a los datos usando una API de estilo ActiveRecord, el código de su controlador recupera un objeto Usuario llamando a la API del método UserMapper.getUser (), por ejemplo. Es ese mapeador el responsable de cargar cualquier objeto asociado de sus respectivas tablas y devolver el objeto de "dominio" de Usuario completado al llamador.

Esencialmente, solo está agregando otra capa de abstracción para hacer que el código sea más manejable. Ya sea que sus clases de DataMapper contengan SQL personalizado sin procesar, o llamadas a una API de capa de abstracción de datos, o incluso accedan a un patrón de ActiveRecord, realmente no importa para el código del controlador que está recibiendo un objeto Usuario agradable y poblado.

De todos modos, así es como lo hago.

Sam McAfee
fuente
5
Parece que simplemente no está familiarizado con ActiveRecord. "ActiveRecord asume una proporción de 1: 1 entre sus tablas". Simplemente no es cierto en absoluto. ActiveRecord tiene todo tipo de magia relacional increíble. Ver api.rubyonrails.org/classes/ActiveRecord/Associations/…
tybro0103
16
@ JoãoBragança: quizás en lugar de un comentario sarcástico, en realidad podrías explicar las dificultades que ocurren cuando los datos de uno están fragmentados, para que el resto de nosotros podamos aprender algo :)
Taryn East
11

Creo que es probable que exista un conjunto muy diferente de razones entre por qué la gente "odia" en ActiveRecord y lo que está "mal" en él.

Sobre el tema del odio, hay mucho veneno hacia todo lo relacionado con Rails. En cuanto a lo que está mal, es probable que sea como toda tecnología y hay situaciones en las que es una buena elección y situaciones en las que hay mejores opciones. La situación en la que no puedes aprovechar la mayoría de las características de Rails ActiveRecord, en mi experiencia, es donde la base de datos está mal estructurada. Si está accediendo a datos sin claves primarias, con cosas que violan la primera forma normal, donde se requieren muchos procedimientos almacenados para acceder a los datos, es mejor que use algo que sea más que un contenedor SQL. Si su base de datos está relativamente bien estructurada, ActiveRecord le permite aprovechar eso.

Para agregar al tema de responder a los comentaristas que dicen que las cosas son difíciles en ActiveRecord con una réplica de fragmento de código

@Sam McAfee Supongamos que tiene una clase de usuario en su dominio y necesita tener referencias o colecciones de otros objetos ya cargados cuando recupera ese objeto de usuario. Los datos pueden provenir de muchas tablas diferentes y un patrón de ActiveRecord puede hacer que sea realmente difícil.

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

Al usar la opción de inclusión, ActiveRecord le permite anular el comportamiento predeterminado de carga diferida.

MattMcKnight
fuente
8

Mi respuesta larga y tardía, ni siquiera completa, pero una buena explicación POR QUÉ odio este patrón, opiniones e incluso algunas emociones:

1) versión corta: Active Record crea una " capa fina " de " enlace fuerte " entre la base de datos y el código de la aplicación. Lo que no resuelve problemas lógicos, de ningún tipo, ni problemas en absoluto. En mi humilde opinión, no proporciona NINGÚN VALOR, excepto algo de azúcar sintáctico para el programador (que luego puede usar una "sintaxis de objeto" para acceder a algunos datos, que existen en una base de datos relacional). El esfuerzo por crear algo de comodidad para los programadores debería (en mi humilde opinión ...) invertirse mejor en herramientas de acceso a bases de datos de bajo nivel, por ejemplo, algunas variaciones de hash_map get_record( string id_value, string table_name, string id_column_name="id" )métodos simples, fáciles, sencillos y similares (por supuesto, los conceptos y la elegancia varían mucho con el idioma utilizado).

2) versión larga: en cualquier proyecto basado en bases de datos en el que tenía el "control conceptual" de las cosas, evitaba la realidad aumentada, y era bueno. Por lo general, construyo una arquitectura en capas (tarde o temprano divide su software en capas, al menos en proyectos de tamaño mediano a grande):

A1) la base de datos en sí, tablas, relaciones, incluso algo de lógica si el DBMS lo permite (MySQL también es adulto ahora)

A2) muy a menudo, hay más que un almacén de datos: sistema de archivos (los blobs en la base de datos no siempre son una buena decisión ...), sistemas heredados (imagínese "cómo" se accederá a ellos, muchas variedades posibles ... pero eso es no es la cuestión...)

B) capa de acceso a la base de datos (en este nivel, los métodos de herramientas, los ayudantes para acceder fácilmente a los datos en la base de datos son muy bienvenidos, pero AR no proporciona ningún valor aquí, excepto algo de azúcar sintáctico)

C) capa de objetos de aplicación: los "objetos de aplicación" a veces son filas simples de una tabla en la base de datos, pero la mayoría de las veces son objetos compuestos de todos modos y tienen una lógica superior adjunta, por lo que invertir tiempo en objetos AR en este nivel es simplemente inútil , una pérdida de tiempo valioso para los codificadores, porque el "valor real", la "lógica superior" de esos objetos debe implementarse sobre los objetos AR, de todos modos, ¡con y sin AR! Y, por ejemplo, ¿por qué querría tener una abstracción de "Objetos de entrada de registro"? El código lógico de la aplicación los escribe, pero ¿debería tener la capacidad de actualizarlos o eliminarlos? suena tonto, y App::Log("I am a log message")algunas magnitudes son más fáciles de usar quele=new LogEntry(); le.time=now(); le.text="I am a log message"; le.Insert();. Y por ejemplo: usar un "Objeto de entrada de registro" en la vista de registro en su aplicación funcionará para 100, 1000 o incluso 10000 líneas de registro, pero tarde o temprano tendrá que optimizar, y apuesto a que en la mayoría de los casos, simplemente lo hará use esa pequeña y hermosa declaración SQL SELECT en la lógica de su aplicación (que rompe totalmente la idea de AR ...), en lugar de envolver esa pequeña declaración en marcos de idea de AR rígidos y fijos con mucho código que lo envuelve y lo oculta. El tiempo que desperdiciaste escribiendo y / o construyendo código AR podría haber sido invertido en una interfaz mucho más inteligente para leer listas de entradas de registro (de muchas, muchas formas, el cielo es el límite). Los programadores deberían atreverse a inventar nuevas abstracciones para realizar su lógica de aplicación que se ajuste a la aplicación deseada, y no volver a implementar estúpidamente patrones tontos., eso suena bien a primera vista!

D) la lógica de la aplicación: implementa la lógica de los objetos que interactúan y la creación, eliminación y lista (!) De los objetos lógicos de la aplicación (NO, esas tareas rara vez deben estar ancladas en los objetos lógicos de la aplicación en sí: ¿la hoja de papel en su escritorio dice ¿Sabes los nombres y las ubicaciones de todas las demás hojas de tu oficina? Olvidas los métodos "estáticos" para enumerar objetos, eso es una tontería, un mal compromiso creado para hacer que la forma humana de pensar se ajuste a [some-not-all-AR-framework-like -] pensamiento AR)

E) la interfaz de usuario - bueno, lo que escribiré en las siguientes líneas es muy, muy, muy subjetivo, pero en mi experiencia, los proyectos que se basan en AR a menudo descuidaron la parte de la interfaz de usuario de una aplicación - se desperdició tiempo en la creación de abstracciones oscuras . Al final, estas aplicaciones hicieron perder mucho tiempo a los codificadores y se sentían como aplicaciones de codificadores para codificadores, con inclinación hacia la tecnología por dentro y por fuera. Los codificadores se sienten bien (trabajo duro finalmente hecho, todo terminado y correcto, según el concepto en papel ...), y los clientes "solo tienen que aprender que tiene que ser así", porque eso es "profesional". ok, lo siento, estoy divagando ;-)

Bueno, es cierto que todo esto es subjetivo, pero es mi experiencia (excluyendo Ruby on Rails, puede ser diferente, y no tengo ninguna experiencia práctica con ese enfoque).

En proyectos pagados, a menudo escuché la demanda de comenzar con la creación de algunos objetos de "registro activo" como un bloque de construcción para la lógica de aplicación de nivel superior. En mi experiencia, esto llamativamente a menudoFue una especie de excusa para que el cliente (una empresa de desarrollo de software en la mayoría de los casos) no tuviera un buen concepto, una gran visión, una descripción general de lo que finalmente debería ser el producto. Esos clientes piensan en marcos rígidos ("en el proyecto hace diez años funcionó bien ..."), pueden desarrollar entidades, pueden definir relaciones de entidades, pueden romper relaciones de datos y definir la lógica básica de la aplicación, pero luego se detienen y entregárselo a usted, y piense que eso es todo lo que necesita ... a menudo carecen de un concepto completo de lógica de aplicación, interfaz de usuario, usabilidad, etc., etc. detalles, y quieren que sigas ese estilo de AR, porque ... bueno, ¿por qué, funcionó en ese proyecto hace años, mantiene a la gente ocupada y en silencio? No lo sé. Pero los "detalles" separar a los hombres de los niños, o ... ¿cómo era el eslogan del anuncio original? ;-)

Después de muchos años (diez años de experiencia en desarrollo activo), cada vez que un cliente menciona un "patrón de registro activo", suena mi alarma. Aprendí a tratar de hacerlos volver a esa fase conceptual esencial , dejar que se lo piensen dos veces, probarlos para mostrar sus debilidades conceptuales o simplemente evitarlos si no son discernidores (al final, ya sabes, un cliente que aún no sabe lo que quiere, tal vez incluso piensa que sabe pero no lo hace, o intenta externalizar el trabajo conceptual a MÍ gratis, me cuesta muchas horas, días, semanas y meses preciosos de mi tiempo, vivir es demasiado corto ...).

Entonces, finalmente: ESTO TODO es la razón por la que odio ese tonto "patrón de registro activo", y lo hago y lo evitaré siempre que sea posible.

EDITAR : Incluso llamaría a esto sin patrón. No resuelve ningún problema (los patrones no están destinados a crear azúcar sintáctico). Crea muchos problemas: la raíz de todos sus problemas (mencionados en muchas respuestas aquí ...) es que simplemente esconde el viejo SQL bien desarrollado y poderoso detrás de una interfaz que, según la definición de patrones, es extremadamente limitada.

¡Este patrón reemplaza la flexibilidad con azúcar sintáctico!

Piénselo, ¿qué problema le resuelve la RA?

Frunsi
fuente
1
Es un patrón arquitectónico de fuente de datos. ¿Quizás debería leer los Patrones de arquitectura de aplicaciones empresariales de Fowler? Tuve pensamientos similares a los tuyos antes de usar el patrón / ORM y descubrir cuánto simplificaba las cosas.
MattMcKnight
1
Comparto tus sentimientos. Huelo algo mal cuando un marco no admite claves compuestas ... Evité cualquier tipo de ORM antes de SQLAlchemy, y a menudo lo usamos en un nivel inferior, como generador de SQL. Implementa Data Mapper y es muy flexible.
Marco Mariani
1
Desde hace dos días que estoy involucrado en un proyecto que usa ORM "de última generación", tal vez las implementaciones estén maduras ahora (en comparación con lo que trabajé hace algunos años). Tal vez, mi mente cambie, lo veremos en tres meses :-)
Frunsi
2
El proyecto está hecho, ¿y sabes qué? ORM todavía apesta, perdí mucho tiempo con problemas de mapeo que se expresan fácilmente de una manera relacional a un montón de "código orientado a objetos". Bueno, por supuesto, el ORM proporcionó formas de expresar consultas en una especie de OOP + SQL-Mix, por supuesto, en una sintaxis similar a OOP, pero eso tomó más tiempo que simplemente escribir una consulta SQL. La abstracción filtrada, el "OOPSQLExperiment" en la parte superior de OOP - permitir a los usuarios escribir SQL en sintaxis de OOP fue la peor idea jamás. No, nunca más.
Frunsi
1
Escribí SQL sin formato para todo durante muchos años. Rails AR me frustra a veces y para las consultas pasivas casi estoy de acuerdo con usted, pero esto es lo que resuelve: 1) Hace que sea adecuadamente difícil guardar los datos que fallan en la validación. 2) Seguimiento de los cambios en la memoria desde la última vez que persiste. 3) Usar el punto 2 para escribir before_savedevoluciones de llamada sensibles para mantener la coherencia dentro del registro. 4) after_commitGanchos para activadores de servicios externos. 5) Un buen DSL para organizar cambios de DDL en conjuntos de cambios (migraciones). (Todavía hay dolor allí, pero no tener un patrón es peor cuando> 1 desarrollador).
Adamantish
6

Algunos mensajes me confunden. Algunas respuestas van a "ORM" vs "SQL" o algo así.

El hecho es que AR es solo un patrón de programación de simplificación en el que aprovecha los objetos de su dominio para escribir el código de acceso a la base de datos.

Estos objetos suelen tener atributos comerciales (propiedades del bean) y algún comportamiento (métodos que normalmente funcionan con estas propiedades).

El AR simplemente dice "agregue algunos métodos a estos objetos de dominio" a las tareas relacionadas con la base de datos.

Y tengo que decir, por mi opinión y experiencia, que no me gusta el patrón.

A primera vista puede sonar bastante bien. Algunas herramientas modernas de Java como Spring Roo utilizan este patrón.

Para mí, el verdadero problema es solo la preocupación por la programación orientada a objetos. El patrón AR te obliga de alguna manera a agregar una dependencia de tu objeto a los objetos de infraestructura. Estos objetos de infraestructura permiten que el objeto de dominio consulte la base de datos a través de los métodos sugeridos por AR.

Siempre he dicho que dos capas son clave para el éxito de un proyecto. La capa de servicio (donde reside la lógica empresarial o se puede exportar a través de algún tipo de tecnología remota, como Web Services, por ejemplo) y la capa de dominio. En mi opinión, si agregamos algunas dependencias (no realmente necesarias) a los objetos de la capa de dominio para resolver el patrón de AR, nuestros objetos de dominio serán más difíciles de compartir con otras capas o aplicaciones externas (raras).

La implementación de Spring Roo de AR es interesante, porque no depende del objeto en sí, sino de algunos archivos AspectJ. Pero si luego no quieres trabajar con Roo y tienes que refactorizar el proyecto, los métodos AR se implementarán directamente en tus objetos de dominio.

Otro punto de vista. Imagina que no usamos una base de datos relacional para almacenar nuestros objetos. Imagine que la aplicación almacena nuestros objetos de dominio en una base de datos NoSQL o simplemente en archivos XML, por ejemplo. ¿Implementaríamos los métodos que realizan estas tareas en nuestros objetos de dominio? No lo creo (por ejemplo, en el caso de XM, agregaríamos dependencias relacionadas con XML a nuestros objetos de dominio ... Realmente triste, creo). Entonces, ¿por qué tenemos que implementar los métodos DB relacionales en los objetos de dominio, como dice el patrón Ar?

En resumen, el patrón AR puede parecer más simple y bueno para aplicaciones pequeñas y simples. Pero, cuando tenemos aplicaciones complejas y grandes, creo que la arquitectura clásica en capas es un mejor enfoque.

Juanjo
fuente
Bienvenido a SO. Aprecio su comentario, pero esta pregunta fue cerrada por no ser constructiva por NullUserException el 17 de diciembre de 2011 a las 1:17
Tony Rad
3

La pregunta es sobre el patrón de diseño de Active Record. No es una herramienta de orm.

La pregunta original está etiquetada con rieles y se refiere a Twitter, que está construido en Ruby on Rails. El marco ActiveRecord dentro de Rails es una implementación del patrón de diseño Active Record de Fowler.

John Topley
fuente
2

Lo principal que he visto con respecto a las quejas sobre Active Record es que cuando crea un modelo alrededor de una mesa y selecciona varias instancias del modelo, básicamente está haciendo un "seleccionar * de ...". Esto está bien para editar un registro o mostrar un registro, pero si desea, por ejemplo, mostrar una lista de las ciudades para todos los contactos en su base de datos, puede hacer "seleccionar ciudad de ..." y obtener solo las ciudades . Hacer esto con Active Record requeriría que seleccione todas las columnas, pero solo use City.

Por supuesto, las diferentes implementaciones manejarán esto de manera diferente. Sin embargo, es un problema.

Ahora, puede evitar esto creando un nuevo modelo para lo específico que está tratando de hacer, pero algunas personas argumentarían que es más esfuerzo que beneficio.

Yo, me gusta Active Record. :-)

HTH

Tim Sullivan
fuente
2
"Hacer esto con Active Record requeriría que seleccione todas las columnas, pero solo use City". En realidad, es extremadamente fácil especificar una cláusula de selección.
MattMcKnight
1

Me encanta la forma en que SubSonic hace una sola columna.
Ya sea

DataBaseTable.GetList(DataBaseTable.Columns.ColumnYouWant)

o bien:

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

Pero Linq sigue siendo el rey cuando se trata de carga diferida.

Lars Mæhlum
fuente
1

@BlaM: A veces simplemente implementé un registro activo para el resultado de una combinación. No siempre tiene que ser la relación Tabla <--> Registro activo. ¿Por qué no "Resultado de una declaración de combinación" <--> Registro activo?

Johannes
fuente
1

Voy a hablar de Active Record como patrón de diseño, no he visto ROR.

Algunos desarrolladores odian Active Record, porque leen libros inteligentes sobre cómo escribir código limpio y ordenado, y estos libros afirman que el registro activo viola el principio de responsabilidad única, viola la regla DDD de que el objeto de dominio debe ser ignorante persistente y muchas otras reglas de este tipo de libros .

Lo segundo, los objetos de dominio en Active Record tienden a ser 1 a 1 con la base de datos, lo que puede considerarse una limitación en algún tipo de sistemas (en su mayoría de n niveles).

Eso es solo cosas abstractas, no he visto la implementación real de ruby ​​on rails de este patrón.

Alex Burtsev
fuente
0

El problema que veo con Active Records es que siempre se trata de una sola mesa. Está bien, siempre que realmente trabaje solo con esa tabla, pero cuando trabaje con datos en la mayoría de los casos, tendrá algún tipo de combinación en alguna parte.

Sí, unirse generalmente es peor que no unirse en absoluto cuando se trata de rendimiento, pero unirse generalmente es mejor que una unión "falsa" leyendo primero toda la tabla A y luego usando la información obtenida para leer y filtrar la tabla B.

Culpa
fuente
@BlaM: Tienes toda la razón. Aunque nunca he usado Active Record, he usado otros sistemas ORM atornillados (particularmente NHibernate), y tengo dos grandes quejas: formas tontas de crear objetos (es decir, archivos .hbm.xml, cada uno de los cuales obtiene compilado en su propio ensamblado) y el impacto en el rendimiento solo se produjo al cargar objetos (NHibernate puede aumentar un proceso de un solo núcleo durante varios segundos al ejecutar una consulta que no carga nada en absoluto, cuando una consulta SQL equivalente casi no requiere procesamiento). No es específico de Active Record, por supuesto, pero encuentro que la mayoría de los sistemas ORM (y sistemas similares a ORM) parecen hacerlo
TheSmurf
Hay muchas alternativas al uso de archivos hbm.xml. Consulte, por ejemplo, NHibernate.Mapping.Attributes y fluent-nhibernate.
Mauricio Scheffer
Sobre el rendimiento de la creación de objetos, nunca me he encontrado con tales problemas de rendimiento, es posible que desee consultar con un generador de perfiles.
Mauricio Scheffer
@mausch: No necesito un generador de perfiles. Es un problema bastante conocido. No sé si se aplica a la última versión (que todavía no estoy usando en mi trabajo). ayende.com/Blog/archive/2007/10/26/…
TheSmurf
4
El uso de: joins o: includes en los hallazgos IE Customer.find (: all,: include =>: contactos,: conditions => "active = 1") hará una unión SQL, no un escaneo completo de la tabla de ninguno de los dos.
Tilendor
0

El problema con ActiveRecord es que las consultas que genera automáticamente pueden causar problemas de rendimiento.

Terminas haciendo algunos trucos poco intuitivos para optimizar las consultas que te dejan preguntándote si hubiera sido más efectivo en el tiempo escribir la consulta a mano en primer lugar.

engtech
fuente
0

Aunque todos los demás comentarios sobre la optimización de SQL son ciertamente válidos, mi principal queja con el patrón de registro activo es que generalmente conduce a una falta de coincidencia de impedancia . Me gusta mantener mi dominio limpio y correctamente encapsulado, lo que el patrón de registro activo generalmente destruye toda esperanza de hacer.

Kevin Pang
fuente
ActiveRecord en realidad resuelve el problema de la falta de coincidencia de impedancia al permitirle codificar de una manera OO contra un esquema relacional.
Mauricio Scheffer
¿Cuidado para elaborar? El consenso general es que los objetos modelados a partir de una base de datos relacional, por definición, no están orientados a objetos (dado que las bases de datos relacionales no giran en torno a conceptos OO como herencia y polimorfismo).
Kevin Pang
Hay tres formas conocidas de asignar la herencia a un esquema relacional. Ref: castleproject.org/ActiveRecord/documentation/trunk/usersguide/…
Mauricio Scheffer
Creo que estás confundiendo el proyecto Castle Active Record OSS con el patrón de diseño de Active Record. La pregunta original (y mi respuesta) se refieren al patrón de diseño. El proyecto Castle Active Record tiene elementos incorporados para ayudar con el desarrollo de OO, pero el patrón en sí no.
Kevin Pang
Solo estaba citando a Castle como referencia. ActiveRecord de RoR implementa solo la herencia de tabla única ( martinfowler.com/eaaCatalog/singleTableInheritance.html ), pero se están considerando las otras estrategias ( blog.zerosum.org/2007/2/16/… )
Mauricio Scheffer
0

Intente hacer una relación polimórfica de varios a varios. No tan fácil. Especialmente cuando no está usando STI.

Alexander Trauzzi
fuente