2010-10-25 17 views
50

En mi base de datos tiene nombres de columna como 'eliminar' o 'escuchar-control', etc. No se pueden cambiar, por lo que me gustaría alias los nombres para evitar problemas en mi aplicación.Alias ​​para nombres de columna en Rails

He encontrado the following code pero no está actualizado (05 ago 2005) y no funciona con Rails 3:

module Legacy 
    def self.append_features(base) 
    super 
    base.extend(ClassMethods) 
    end 
    module ClassMethods 
    def alias_column(options) 
     options.each do |new_name, old_name| 
     self.send(:define_method, new_name) { self.send(old_name) } 
     self.send(:define_method, "#{new_name}=") { |value| self.send("#{old_name}=", value) } 
     end 
    end 
    end 
end 

ActiveRecord::Base.class_eval do 
    include Legacy 
end 

¿Cómo puedo asignar un alias a los nombres de las columnas? ¿Es posible?

+0

No veo cuál es el problema con el uso de 'eliminar' y 'escuchar-control' como nombres de columna? ¿Te encuentras con un error u otra cosa? – Ariejan

+3

listen-control causa problemas porque tiene un guion en el nombre, lo que lo convierte en un atributo de objeto ruby ​​no válido. Ruby interpretará "object.listen-control" como "object.listen, menos control". Y eliminar podría ser una palabra clave reservada. No sé por qué querrías hacer esto. A veces, la respuesta correcta es dejar de tratar de luchar contra el rubí o los rieles. –

+0

'define_method (" listen-control ", Proc.new {puts" bingo "})' then 'send (" listen-control ")'. ¿Dónde está el problema? – rthbound

Respuesta

0

Como dijo Jaime, esos nombres pueden causar problemas.

En ese caso, use algunos nombres razonables. Su GUI nunca debe dictar cómo se nombran sus columnas.

Sugerencias: is_deleted o deleted_at, listen_control

A continuación, cambie su punto de vista en consecuencia, eso es mucho más fácil que luchar ActiveRecord y su base de datos.

+3

... y cambiar la aplicación principal que lee y escribe en/desde la base de datos con solo estos nombres? – user486421

6

Los nombres de los métodos de alias no resolverán su problema. Como mencioné en mi comentario anterior, no puede tener guiones en el método Ruby o nombres de variables, porque Ruby los interpretará como un "menos". así:

object.listen-control 

será interpretado por rubí como:

object.listen - control 

y fallará. El fragmento de código que encontró podría estar fallando debido a ruby ​​1.9, no a los rieles 3. Ruby 1.9 no le permite llamar al .send en métodos protegidos o privados, como 1.8.

Dicho esto, entiendo que haya ocasiones en que los nombres de las columnas de las bases de datos antiguas no se vean muy bien y usted quiera limpiarlos. Crea una carpeta en tu carpeta lib llamada "bellmyer". A continuación, cree un archivo llamado "create_alias.rb", y añadir lo siguiente:

module Bellmyer 
    module CreateAlias 
    def self.included(base) 
     base.extend CreateAliasMethods 
    end 

    module CreateAliasMethods 
     def create_alias old_name, new_name 
     define_method new_name.to_s do 
      self.read_attribute old_name.to_s 
     end 

     define_method new_name.to_s + "=" do |value| 
      self.write_attribute old_name.to_s, value 
     end 
     end 
    end 
    end 
end 

Ahora en su modelo que necesita aliasing, se puede hacer esto:

class User < ActiveRecord::Base 
    include Bellmyer::CreateAlias 
    create_alias 'name-this', 'name_this' 
end 

Y será un alias correctamente. Está utilizando los métodos read_attribute y write_attribute de ActiveRecord para acceder a esas columnas de la tabla sin llamarlas como métodos ruby.

+0

Gracias por responder, pero he probado su solución y me aparece el error: SyntaxError (/usr/lib/ruby/gems/1.9.1/gems/activemodel-3.0.0/lib/active_model/attribute_methods.RB: 229: error de sintaxis, inesperada '' de envío (: vm-password =, * args) ^): cuando se define: alias_attribute "vm_password", "vm-contraseña" y tratar de conseguir "vm_password ". – user486421

+0

¡Encontré una solución! Ver la edición de mi respuesta anterior. –

+0

¡Muchas gracias! Lo probé y encontré: 1. En user.rb necesita agregar la primera línea: require 'bellmyer/create_alias.rb' 2. Cuando nadie registra en la tabla, su método funciona bien. Con uno o más registros, los rieles reciben un error: ActionView :: Template :: Error (/usr/lib64/ruby/gems/1.9.1/gems/activemodel-3.0.0/lib/active_model/attribute_methods.rb:273: error de sintaxis , inesperado '-', esperando keyword_end undef: vm-password? ... 3. Con nombre de campo como 'eliminar', este método no funciona porque 'eliminar' es el nombre del método. – user486421

123

Declare esto en su modelo.

alias_attribute :new_column_name, :column_name_in_db 
+0

Este método no funciona cuando una columna de tabla tiene un nombre con un guion. La columna de la tabla debe correlacionarse con un nombre de método de ruby ​​válido tal como está, para poder usar esto. –

+1

¿funcionaría esto? 'alias_attribute: 'new-column-name',: 'column-name-in-db'' –

+0

:' foo 'es idéntico a: foo. : 'new-column-name' es un Símbolo. Supongo que no lo has intentado. ;) –

Cuestiones relacionadas