Rails中列名的别名

use*_*421 65 database activerecord ruby-on-rails ruby-on-rails-3

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

我发现以下代码但它已过时(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
Run Code Online (Sandbox Code Playgroud)

我如何为列名称添加别名?可能吗?

Shr*_*yas 143

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

alias_attribute :new_column_name, :column_name_in_db
Run Code Online (Sandbox Code Playgroud)

  • 注意:Arel不会注意这一点. (8认同)
  • ps这只改变了方法别名,如果你有像'User.where("login like?",params [:login])`这样的代码,你必须自己将它(这里的登录名)改为新的列名. (2认同)
  • 这不适用于cache_key.`alias_attribute:last_modified_time,:updated_at`不会根据上次修改的时间戳生成cache_key. (2认同)
  • 2017年更新:Arel仍然没有注意到这一点. (2认同)

Jai*_*yer 7

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

object.listen-control
Run Code Online (Sandbox Code Playgroud)

将由ruby解释为:

object.listen - control
Run Code Online (Sandbox Code Playgroud)

并将失败.您找到的代码片段可能因为ruby 1.9而导致失败,而不是rails 3. Ruby 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
Run Code Online (Sandbox Code Playgroud)

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

class User < ActiveRecord::Base
  include Bellmyer::CreateAlias
  create_alias 'name-this', 'name_this'
end
Run Code Online (Sandbox Code Playgroud)

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


Ari*_*jan 0

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

在这种情况下,请使用一些有意义的名称。你的 GUI 永远不应该规定你的列是如何命名的。

意见建议:is_deleteddeleted_at,listen_control

然后,相应地改变你的视图,这比对抗 ActiveRecord 和你的数据库要容易得多。

  • ...并更改仅使用此名称在数据库中读取和写入的主应用程序? (4认同)