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)
别名方法名称不能解决您的问题.正如我在上面的评论中提到的,你不能在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_attribute和write_attribute方法来访问这些表列而不将它们称为ruby方法.
正如 Jaime 所说,这些名称可能会引起问题。
在这种情况下,请使用一些有意义的名称。你的 GUI 永远不应该规定你的列是如何命名的。
意见建议:is_deleted或deleted_at,listen_control
然后,相应地改变你的视图,这比对抗 ActiveRecord 和你的数据库要容易得多。
| 归档时间: |
|
| 查看次数: |
42116 次 |
| 最近记录: |