Rails中列名的别名

时间:2010-10-25 13:10:40

标签: ruby-on-rails database ruby-on-rails-3 activerecord

在我的数据库中有列名,例如'delete'或'listen-control'等。这些不能更改,所以我想对名称进行别名,以避免我的应用程序出现问题。

我发现the following code但它已过时(2005年8月5日)并且不适用于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

我如何为列名设置别名?有可能吗?

3 个答案:

答案 0 :(得分:141)

在您的模型中声明这一点。

alias_attribute :new_column_name, :column_name_in_db

答案 1 :(得分:7)

别名方法名称无法解决您的问题。正如我在上面的评论中提到的,你不能在ruby方法或变量名中使用破折号,因为ruby会将它们解释为“减号”。这样:

object.listen-control

将由ruby解释为:

object.listen - control

并且会失败。您找到的代码片段可能因为ruby 1.9而不是rails 3而失败.Rublin 1.9不允许您再次使用受保护或私有方法调用.send,例如1.8以前。

话虽如此,我确实理解有时候旧的数据库列名看起来不太好,你想要清理它们。在lib文件夹中创建一个名为“bellmyer”的文件夹。然后创建一个名为“create_alias.rb”的文件,并添加:

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

现在,在需要别名的模型中,您可以执行以下操作:

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

它将是正确的别名。它使用ActiveRecord的read_attributewrite_attribute方法来访问这些表列而不将它们称为ruby方法。

答案 2 :(得分:0)

正如Jaime所说,这些名字可能会引发问题。

在这种情况下,请使用一些明智的名称。您的GUI永远不应该指定列的命名方式。

建议:is_deleteddeleted_atlisten_control

然后,相应地更改您的视图,这比对抗ActiveRecord和您的数据库更容易。