2010-10-25 11 views
50

Nel mio database sono presenti nomi di colonne come "cancella" o "ascolta controllo" e così via. Questi non possono essere modificati, quindi mi piacerebbe fare l'alias dei nomi in modo da evitare problemi nella mia applicazione.Alias ​​per nomi di colonne in Rails

ho trovato the following code ma non è aggiornato (05 ago 2005) e non funziona 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 

Come posso alias i nomi delle colonne? È possibile?

+0

Non vedo quale sia il problema con l'uso di 'delete' e 'listen-control' come nomi di colonne? Ti imbatti in un errore o qualcos'altro? – Ariejan

+3

listen-control causa problemi perché ha un trattino nel nome, che lo rende un attributo di oggetto ruby ​​non valido. Ruby interpreterà "object.listen-control" come "object.listen, meno controllo". E l'eliminazione potrebbe essere una parola chiave riservata. Non so perché vorresti farlo. A volte la risposta giusta è smettere di cercare di combattere rubino o rotaie. –

+0

'define_method (" listen-control ", Proc.new {puts" bingo "})' then 'send (" listen-control ")'. Dov'è il problema? – rthbound

risposta

0

Come diceva Jaime, quei nomi potrebbero causare problemi.

In tal caso, utilizzare alcuni nomi sensibili. La tua GUI non dovrebbe mai imporre come vengono denominate le tue colonne.

Suggerimenti: is_deleted o deleted_at, listen_control

Quindi, modificare la visualizzazione di conseguenza, questo è più facile che combattere ActiveRecord e il database.

+3

... e cambia l'applicazione principale che legge e scrive in/da database con solo questi nomi? – user486421

6

I nomi dei metodi di alias non risolveranno il problema. Come ho accennato nel mio commento sopra, non puoi avere trattini nel metodo ruby ​​o nomi di variabili, perché ruby ​​li interpreterà come un "meno". così:

object.listen-control 

sarà interpretata dai rubino come:

object.listen - control 

e sarà sicuro. Lo snippet di codice che hai trovato potrebbe non funzionare a causa di Ruby 1.9, non di rails 3. Ruby 1.9 non ti permette di chiamare più .send su metodi protetti o privati, come ad esempio 1.8.

Detto questo, capisco che ci sono momenti in cui i vecchi nomi delle colonne del database non sembrano molto belli e si desidera pulirli. Crea una cartella nella cartella lib chiamata "bellmyer". Quindi creare un file chiamato "create_alias.rb", e aggiungere questo:

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 

Ora nel modello che ha bisogno di aliasing, si può fare questo:

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

E sarà alias correttamente. Sta usando i metodi read_attribute e write_attribute di ActiveRecord per accedere a quelle colonne della tabella senza chiamarle come metodi ruby.

+0

Grazie per la risposta, ma sono stato testato la soluzione e ho ricevuto l'errore: SyntaxError (/usr/lib/ruby/gems/1.9.1/gems/activemodel-3.0.0/lib/active_model/attribute_methods.RB: 229: errore di sintassi, inaspettata '' send (: vm-password =, * args) ^): quando definito: alias_attribute "vm_password", "vm-password" e cercare di ottenere "vm_password ". – user486421

+0

Ho trovato una soluzione! Vedi la modifica della mia risposta sopra. –

+0

Grazie mille! L'ho provato e trova: 1. In user.rb occorre aggiungere la prima riga: require 'bellmyer/create_alias.rb' 2. Quando nessuno registra nella tabella, il metodo funziona correttamente. Con uno o più record rails si verifica un errore: ActionView :: Template :: Error (/usr/lib64/ruby/gems/1.9.1/gems/activemodel-3.0.0/lib/active_model/attribute_methods.rb:273: errore di sintassi , inaspettato '-', in attesa di keyword_end undef: vm-password? ... 3. Con nome campo come "cancella" questo metodo non funziona perché "cancella" è il nome del metodo. – user486421

123

Dichiarare questo nel modello.

alias_attribute :new_column_name, :column_name_in_db 
+0

Questo metodo non funziona quando una colonna della tabella ha un nome con un trattino. La colonna della tabella deve mappare il nome di un metodo ruby ​​valido così com'è, per poterlo utilizzare. –

+1

funzionerebbe? 'alias_attribute: 'new-column-name',: 'column-name-in-db'' –

+0

:' foo 'è identico a: foo. : "new-column-name" è un simbolo. Suppongo che tu non ci abbia provato. ;) –

Problemi correlati