微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ActiveRecord Rails 4

如何解决ActiveRecord Rails 4

ActiveRecord 是否有任何认读取器方法,以便每当我从数据库获取值时,都会调用此读取器方法?(Property.last.nameStudent.first.course )。我想以这种方式覆盖此方法,如果数据类型是字符串,则将其转换为大写。我不想在每个模型中为每一列添加单独的 getter。

例如:

def reader(column)
  column.upcase if column.is_a? String
end

解决方法

有一个方法 ActiveRecord::AttributeMethods::Read#read_attribute 在类型转换后返回值。所以猴子修补(或改进)这个方法可能会给你你想要的 - 所有字符串值都将被转换。

但我会认真地重新考虑这种方法:如果您不想射自己的腿,所有数据转换都应该是明确可见的。

这并不意味着您不能避免手动重新定义 getter。例如,你可以做某事。像这样(免责声明:快速而肮脏的例子):

module TransformValues
  def transform(*attributes_to_transform,transformer: nil,&block)
    attributes_to_transform.each do |attribute_name|
      define_method attribute_name do
        case transformer = (block || transformer)
        when Proc
          transformer.call(self[attribute_name])
        when Symbol
          self[attribute_name].__send__(transformer)
        else
          self[attribute_name]
        end
      end
    end
  end
end

# and then

class User < ActiveRecord::Base
  extend TransformValues
  transform :first_name,:last_name,transformer: :upcase
  transform :whatever do |val|
    do_smth_with(val)
  end
  # etc
end

在这种情况下,您的所有转换或多或少都保持明确,而无需大量手动编写的样板。如果您所需要的只是大写的字符串,那么所有这些都可以大大简化为 smth。喜欢

module UpcaseAttributes
  def always_upcase(*attributes_to_transform)
    attributes_to_transform.each do |attribute_name|
      define_method attribute_name do
        case value = self[attribute_name]
        when String
          value.upcase
        else
          value
        end
      end
    end
  end
end

class User < ActiveRecord::Base
  extend UpcaseAttributes
  always_upcase :first_name,:last_name
end

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。