2010-02-13 23 views
6

En la aplicación que estoy construyendo, los usuarios pueden especificar relaciones entre tablas.¿Cómo agrego relaciones en tiempo de ejecución usando DBIx :: Class y Catalyst?

Como solo lo determiné en el tiempo de ejecución, no puedo especificar las relaciones has_many or belongs_to en los módulos de esquema para el inicio.

Así que dos tablas; sistema y lugar, me gustaría agregar la relación para unir registros entre ellos.

que tienen parte de la solución a continuación:

$rs = $c->model('DB::system')->result_source; 
$rs->add_relationship('locations','DB::place',{'foreign.fk0' => 'self.id'}); 

Así la columna fk0 sería la asignación de clave externa a la ubicación de la clave primaria id.

Sé que debe haber una nueva inscripción para permitir el acceso futuro a la relación, pero no puedo resolverlo.

+3

¿Estás seguro de que tus usuarios realmente cambian el esquema de la base de datos? Eso es exactamente equivalente a permitirles editar el código fuente. No necesariamente necesita modelar su "interfaz de usuario" con DBIx :: Class. Probablemente desee desarrollar alguna representación intermedia que proporcione la funcionalidad que desee y mantener el código y el esquema de la base de datos corregidos. – jrockway

+1

También existe DBIx :: Class :: Schema :: Loader, si está rastreando una base de datos cambiante que no controla, o algo así. Pero tenga en cuenta que los cambios en el esquema de la base de datos cambiarán el comportamiento de su aplicación. Si su código es estático y su esquema de base de datos es dinámico, es casi seguro que algo está mal. – jrockway

+0

Estoy explorando la posibilidad de usar mi propio esquema/diccionario de datos superpuesto en la base de datos real. Tengo una tabla de "columnas" y una tabla de "tablas". Estos se usan para mapear los nombres y atributos de tabla y columna seleccionados por el usuario en un espacio de tabla genérico subyacente. Como tal, los usuarios pueden elegir agregar relaciones entre tablas en tiempo de ejecución. Me gustaría acceder a esta relación a través de DBIx. Estoy construyendo una interfaz intermedia para ocultar el esquema genérico y necesito esta capacidad. Gracias, -Joe – Joe

Respuesta

1

No creo que pueda volver a definir estas relaciones después de que una aplicación ya se esté ejecutando. Al menos no sin descartar ningún objeto DBIC existente y volver a crearlos desde cero. En ese punto, sería más fácil simplemente reiniciar su aplicación, sospecho.

Si está contento definiendo estas cosas dinámicamente en compile vez, eso es posible ... hacemos algo similar en una de nuestras aplicaciones.

Si eso le fuera útil, puedo proporcionar un código de muestra.

El módulo DBIx::Class::ResultSet::View puede proporcionar una aproximación aproximada de lo que está buscando, permitiéndole ejecutar código arbitrario, pero recuperando los resultados como objetos DBIx.

Mi opinión general sobre este tipo de cosas es que cualquier capa de abstracción (y un ORM es una capa de abstracción) tiene la intención de hacer la vida más fácil. Cuando se interpone en hacer que su aplicación haga lo que quiere, ya no hace la vida más fácil, y debe descartarse (para ese uso específico, no necesariamente para cada uso). Por esta razón, sugeriría usar DBI, como sugirió en uno de sus comentarios. Sospecho que hará su vida mucho más fácil en este caso.

+0

+1 para "cuando se ponga en medio ..." comentario. Una de las razones por las que todavía prefiero Class :: DBI a través de DBIC - No creo que se interponga en el camino. – RET

0

Lo he hecho llamando a los métodos apropiados en las fuentes de resultados relevantes, p. $resultset->result_source-><relationship method>. Funciona incluso en una aplicación activa.

Cuestiones relacionadas