web-dev-qa-db-fra.com

Alias ​​pour les noms de colonne dans Rails

Dans ma base de données a des noms de colonnes tels que "supprimer" ou "écouter-contrôle" et ainsi de suite. Ceux-ci ne peuvent pas être modifiés, je voudrais donc alias les noms afin d'éviter les problèmes dans mon application.

J'ai trouvé le code suivant mais il est obsolète (05 août 2005) et ne fonctionne pas avec 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

Comment puis-je alias les noms de colonne? C'est possible?

63
user486421

Déclarez cela dans votre modèle.

alias_attribute :new_column_name, :column_name_in_db
142
Shreyas

Les noms de méthode d'alias ne résoudront pas votre problème. Comme je l'ai mentionné dans mon commentaire ci-dessus, vous ne pouvez pas avoir de tirets dans Ruby méthode ou noms de variables, car Ruby les interprétera comme un "moins"). alors:

object.listen-control

sera interprété par Ruby comme:

object.listen - control

et échouera. L'extrait de code que vous avez trouvé peut échouer en raison de Ruby 1.9, pas Rails 3. Ruby 1.9 ne permet pas tu appelles .send sur des méthodes protégées ou privées, comme 1.8 auparavant.

Cela étant dit, je comprends qu'il y a des moments où les anciens noms de colonne de base de données ne sont pas très jolis et que vous souhaitez les nettoyer. Créez un dossier dans votre dossier lib appelé "bellmyer". Créez ensuite un fichier appelé "create_alias.rb" et ajoutez ceci:

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

Maintenant, dans votre modèle qui nécessite un alias, vous pouvez le faire:

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

Et il alias correctement. Il utilise le read_attribute et write_attribute méthodes d'ActiveRecord pour accéder à ces colonnes de table sans les appeler en tant que méthodes Ruby.

7
Jaime Bellmyer

Comme l'a dit Jaime, ces noms pourraient causer des problèmes.

Dans ce cas, utilisez des noms sensés. Votre interface graphique ne doit jamais dicter le nom de vos colonnes.

Suggestions: is_deleted ou deleted_at, listen_control

Ensuite, changez votre vue en conséquence, c'est beaucoup plus facile que de combattre ActiveRecord et votre base de données.

0
Ariejan