En Model-Driven Design, que tienen lógicas Entidades en su aplicación, y estas entidades pueden asignar a varias tablas en la base de datos física. Por supuesto, necesita ejecutar SQL más complejo para obtener una entidad completa, y la clase de modelo es el lugar donde se implementan estas relaciones.
Creo que ActiveRecord y su tipo están bien para consultas sencillas en una sola tabla, pero tratar de forzar el uso de estos patrones para consultas complejas es muy difícil. Afortunadamente, ya contamos con un lenguaje conciso y específico de dominio que puede usar para especificar consultas complejas: SQL.
Por lo tanto, en su clase Model, tendría métodos para realizar tareas lógicas a nivel de aplicación, como getCustomersForFeature()
. En el código para ese método, debe escribir una consulta específica, ya sea con métodos ActiveRecord o con SQL directo si es necesario. Por lo tanto, el diseño concreto de su base de datos está encapsulado en un solo lugar, en la clase Modelo.
Esto significa que debemos romper el acoplamiento entre el Modelo y la Mesa. La relación OO entre un modelo y una clase ActiveRecord no es IS-A - es HAS-A (o tiene muchas).
su comentario Re: ¿Cuál es nuestro modelo? Si su aplicación necesita trabajar principalmente con los clientes como una entidad, y trata las características como más o menos un atributo de los clientes, entonces su modelo sería Clientes, y ocultaría el hecho de que las características se almacenan en una tabla separada en la base de datos. . El modelo de Clientes usaría internamente ActiveRecord o SQL simple para recopilar los datos necesarios para proporcionar una vista completa del objeto complejo que es un cliente con sus atributos multivalor asociados.
Sin embargo, ¿qué ocurre si su aplicación también tiene la necesidad de trabajar con Características directamente? Por ejemplo, una pantalla de administrador donde puede obtener informes basados en características o crear nuevas características. Entonces sería torpe acceder a las características a través del modelo del Cliente. Entonces necesitarías un modelo de Características después de todo. Solo tendría diferentes métodos para implementar las operaciones que necesita hacer con las Características.
Cada clase de modelo debe exponer una API de solo las cosas que necesita hacer con ese modelo. No hay necesidad de ser simétrico.El hecho de que su modelo de Cliente pueda captar a todos los clientes que tienen una característica determinada no significa necesariamente que su modelo de Características necesite obtener todas las funciones para un cliente determinado. Siga la regla YAGNI.
Pero después de haber creado su modelo de Cliente y su modelo de Características, ¿esto no conduce a la duplicación de la lógica que conoce acerca de las relaciones entre las tablas? Sí, podría. Este es uno de los muchos problemas que entran dentro del alcance del object-relational impedance mismatch.
Agregué una respuesta Wiki de la comunidad a esta pregunta, que resume lo que creo que son los enfoques disponibles basados en las respuestas aquí y la lectura adicional. Esto no quita nada a las otras respuestas aquí, pero es el enfoque orientado a patrones lo que estaba buscando, con la idea Agregado incluida. Dudo en seleccionarlo como la "respuesta aceptada" (¿puedo hacerlo con mi propia respuesta?) Hasta que haya sido sujeto a más escrutinio. –