如何在Rails模型中覆盖一个列?

20

我有一个数据库表的模型,我想覆盖该特定表的列名。我应该如何实现?

例如,让我的表称为DUMMY,并且它有一个名为col_a的列。

col_a
20
34
42
23
12
我将执行 @dummy.col_a。现在这个方法应该对以0结尾的数字返回0,对于其他所有情况,它应该返回原始值。我可以通过定义一个新方法来实现,但我想覆盖列名本身。请帮忙。
4个回答

38

你可以重写col_a方法。使用read_attribute方法来读取数据库中的值。代码如下:

def col_a
  if self.read_attribute(:col_a).to_s.end_with?('0')
    0
  else
    self.read_attribute(:col_a)
  end
end

对于编程新手来说,这是定义写入场景的方法:def attribute_name=(value) self.write_attribute(value) end此外,检查其他答案以查看自2017年以来是否可以使用super代替read_attributewrite_attribute - nilsandrey

12

你可以简单地定义一个与列名相同的方法。要获取实际的列值,请使用self[column_name]。因此,以下内容应该有效:

class Dummy < ActiveModel::Base
  def col_a
    self[:col_a] % 10 == 0 ? 0 : self[:col_a]
  end
end

(假设 col_a 是整数。)


应该是 self[:col_a] % 10 != 0 ? self[:col_a] : 0 或者 (self[:col_a]%10).zero? ? 0 : self[:col_a] - fl00r
是的 - 我假设0会在这里被评估为false,但它并没有。已修复。 - Thilo

8

我来晚了,但是一个非常优雅的方法是简单地使用 super

class Dummy < ApplicationRecord
  def col_a
    super % 10 === 0 ? 0 : super
  end
end

5
您可以按照文档描述的方法重写默认存取器来实现这一点。所有列值都可以通过Active Record对象上的基本存取器自动获取,但有时您可能希望专门定制此行为。这可以通过重写默认存取器(使用与属性相同的名称)并调用read_attribute(attr_name)write_attribute(attr_name, value)来实际更改内容来完成。
请参阅“覆盖默认存取器”部分以了解更多信息。

现代浏览器支持滚动到文本片段,因此我粘贴了一个直接链接;)https://api.rubyonrails.org/classes/ActiveRecord/Base.html#class-ActiveRecord::Base-label-Overwriting+default+accessors:~:text=Overwriting%20default%20accessors - nilsandrey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接