【问题标题】:Default reader for ActiveRecord Rails 4ActiveRecord Rails 4 的默认阅读器
【发布时间】:2021-07-17 06:20:35
【问题描述】:

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

例如:

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

【问题讨论】:

  • 谢谢。但是如果我添加一个新字段,我需要添加一个新的 getter,这不是我想要的。我想要一个适用于所有可以被覆盖的字段的默认 getter 方法。
  • 可能可以在数据库连接级别进行设置,具体取决于您的数据库类型。你用的是什么数据库?

标签: ruby ruby-on-rails-4 methods overriding reader


【解决方案1】:

有一个方法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

【讨论】:

  • 谢谢。但这适用于 self.read 或 self.read_attribute 吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-10-19
  • 1970-01-01
  • 2015-11-13
  • 2015-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多