references rails multiple foreign belong association ruby-on-rails inheritance

ruby-on-rails - foreign - rails multiple table inheritance



Herencia de tabla única y dónde usarla en Rails (4)

Caracterizar a las ITS como más útiles cuando los atributos son los mismos pero el comportamiento difiere es "acertado", pero posiblemente un poco limitante. Me gusta usar STI cuando, como su nombre indica, existe una clara relación de herencia de estilo OO, en lugar de la relación de estilo de base de datos entre objetos de diferentes tipos.

Si hay un código común entre bots y usuarios, diría que STI suena como un ganador. Si solo hay algunos atributos comunes, probablemente sea menos aplicable, pero aún así vale la pena intentarlo.

Soy una persona muy experimental, así que mi recomendación es intentarlo. Registre su código y refactorice los modelos en una relación de ITS. Vea si realmente hace que las cosas se sequen, o simplemente cambia un grupo de dolores de cabeza por algún otro problema.

Una cosa de la que creo que no verá mucho beneficio es secar sus controladores. En mi experiencia, los modelos de STI a menudo no se traducen en controladores relacionados de manera similar. Pero eso sería algo más con lo que experimentar. A veces hay una victoria, otras veces no.

Estoy atrapado en un extraño problema de diseño,

Estoy trabajando en dos tipos de perfiles Modelos,

  • Perfil de usuario (pertenece al usuario)
  • otros que se mantienen en el sitio como "bots" (no pertenecen a nadie)

El comportamiento OO típico de estos dos tipos de perfiles es el mismo, pero solo los atributos / propiedades importantes son comunes (los muy importantes son 5-6 en número), mientras que otras propiedades como "intereses, etc." (casi 10-15 propiedades) no están ahí. para perfiles de bot

El codificador que trabajó en este anteriormente creó modelos / Controladores separados para perfiles de bot / Perfiles de usuario que crea mucha redundancia en todas partes y también como era de esperar para mantener, escribir pruebas, etc. Quise SECAR esto, al menos para resolver algunos / todos de estos problemas de redundancia.

Alguien sugirió Single Table Herencia como una solución

Alguien sugirió Usar asociaciones polimórficas en su lugar.

¿Cuál es el mejor enfoque? ¿Cuándo usamos realmente STI?

Mi propio pensamiento fue que STI se usa mejor cuando los atributos son los mismos para los Modelos y difieren en el comportamiento.

¿Pensamientos sobre qué puedo hacer?


Escribí un artículo sobre este tema, que incluye algunos consejos para trabajar con ITS:

Herencia de tabla única en rieles

En resumen: es necesario que exista una relación de herencia de estilo OO clara entre los objetos (como lo expresa elocuentemente la womble), no solo algunos datos compartidos. Si no existe una jerarquía de clases natural y obvia, un diseño de ITS puede volverse difícil de mantener a medida que su aplicación evoluciona.

En segundo lugar, debe considerar si es importante tener todos los datos en una tabla. Con asociaciones polimórficas, las consultas de su base de datos se volverán más complejas y probablemente más lentas. Si planea listar todos los objetos juntos en el sitio (por ejemplo, en una tabla), entonces STI puede ser el camino a seguir.

En tercer lugar, asegúrese de que sus clases secundarias no tengan demasiados atributos únicos. Con todos los datos en una tabla, no quiere muchas columnas no globales. No solo ocupan espacio (no es una preocupación importante), sino que hacen que la estructura de datos sea confusa. Si tiene columnas "especiales", debe explicarlas explícitamente en su código.

Por último, si usa STI, le recomiendo usar un solo controlador para todos sus modelos secundarios. La función principal de un controlador es proporcionar acceso a los objetos, y si los objetos necesitan ser accedidos de maneras muy diferentes, entonces STI puede no haber sido la opción de diseño correcta para empezar.

Mira mi artículo (enlace de arriba) para obtener algunos consejos más útiles.


Probablemente usaría STI o ninguna característica especial. Es posible que pueda llamar a todo un Perfil y sabrá si era un "bot" si su usuario era nulo. También podría almacenar un campo "tipo" sin usar STI.

Ciertas cosas afectarían mi decisión de usar STI:

  • Si hay una lógica específica de bot
  • Cuántos bots hay contra los perfiles de los usuarios (una pequeña cantidad de bots significa que STI está bien, muchos bots y podría guardarlos en otro lugar)

La razón para evitar las ITS es que a veces puede interponerse en su camino. Por ejemplo, puede ser bastante molesto cambiar un objeto de un tipo a otro (un Bot a un perfil en este caso). A veces, un campo simple de "tipo" es mejor.

Vale la pena señalar que probablemente desee una clase base común si usa STI. Así que puede querer Profile , BotProfile , y UserProfile . Los nombres son tu decisión. :)


Una gotcha de Rails STI: la mayoría de los complementos (y demás) no lo admiten por completo. Te encontrarás parchando muchos de los más comunes.