2010-09-17 12 views
7

He estado construyendo una aplicación Rails que realiza funciones de contabilidad. Como parte de esto, tengo un modelo con el nombre de clase Transaction. Hasta ahora todo bien, he estado construyendo esta funcionalidad por un mes más o menos, y todo está funcionando como se esperaba.Resolviendo un conflicto de nombre de clase en una aplicación Rails

Hasta ahora ...

acabo de descubrir algunos mayores funcionalidad de informes que se desarrolló hace meses usando la biblioteca Ruport ha dejado de funcionar. Parece que Ruport, al generar archivos PDF, requiere una biblioteca que también tiene una clase/módulo llamado Transaction.

TypeError in Admin/team reportsController#generate 
Transaction is not a module 

... 

This error occurred while loading the following files: 
    pdf/writer 
    transaction/simple 

Así que, estoy buscando una solución rápida aquí. Uno que afortunadamente no implica el cambio de nombre de mi modelo Transaction y la refactorización del código de las últimas semanas.

Mirando hacia adelante a algunas sugerencias inteligentes :)

Respuesta

7

Creo que el problema se debe a Ruport que requiere el PDF :: Writer gem, que a su vez requiere Transaction :: Simple gem que define el módulo Transaction.

Ciertamente hay un método #transaction en ActiveRecord, pero no creo que exista un módulo Transaction o clase dentro de Rails. Estaré feliz de ser corregido en eso.

El espaciado de nombres suele ser la mejor práctica para evitar conflictos de nombres como este. P.ej.

module Account 
    class Transaction < ActiveRecord::Base 
    .... 
    end 
end 

Sin embargo, los modelos ActiveRecord de espacios de nombres pueden arrojar otros problemas.

Por mucho tiempo que sea, cambiar el nombre de su modelo de transacción puede ser la mejor opción.

Aún puede mantener su tabla de base de datos de transacciones existente si lo desea, por lo que sus migraciones no tienen que cambiar, poniendo self.table_name = "transactions" dentro de su modelo.

Sus asociaciones con otros modelos también pueden llamarse "transacción (es)" al especificar el nombre de clase en su llamada de asociación. P.ej.

class User < ActiveRecord::Base 

    has_many :transactions, :class_name => "AccountTransaction" 

end 

Esas dos sugerencias pueden o no ahorrarle algo de tiempo.

+0

Gracias. He cambiado su respuesta a la respuesta aceptada, ya que describe con más precisión el problema específico que tengo, ¡aunque Yannis, la respuesta también es correcta! Al final, decidí cambiar el nombre de mi modelo, tabla de base de datos y todas las asociaciones usando old-skool find and replace;) – aaronrussell

+0

En la versión más nueva de Rails, 'set_table_name' es solo' self.table_name = ', vea http://api.rubyonrails.org/classes/ActiveRecord/ModelSchema/ClassMethods.html#method-i-table_name-3D –

0

su problema puede venir del hecho de que la transacción es también una palabra reservada en los carriles ...

+0

lo es? ¡Maldita sea! Pero gracias por informarme ... – aaronrussell

+4

Rails es solo una biblioteca de Ruby, no puede agregar palabras clave al lenguaje Ruby. –

+1

Puede ser simplemente una biblioteca, pero puede imponer límites a la denominación de las cosas que la usan (aunque el lenguaje no las impone).Solo mire el problema que entra cuando trata de usar el nombre de columna 'tipo' ... –

13

Ya respondí y viejo, pero vine aquí con el mismo problema, pero lo resolvió de una manera diferente.

Tengo dos modelos llamados Pull and Query. Intentar hacer referencia a Query.some_static_method() dentro de un método en Pull dio como resultado una resolución de Query a ActiveRecord::AttributeMethods::Query:Module.

lo resolvió poniendo el espacio de nombres vacío delante de ella con ::Query.some_static_method()

+0

¡Buena respuesta, no sabía sobre el espacio de nombres vacío! –

+0

Solución elegante. ¿Podría explicar exactamente por qué/cómo funciona? – cph2117

+0

@ cph2117, todo lo que realmente hace es ser explícito sobre qué espacio de nombres es para encontrar 'Query'. – hometoast

Cuestiones relacionadas