覆盖ActiveRecord finder的类型转换

时间:2010-02-04 17:11:15

标签: ruby-on-rails activerecord

我想在使用像.first或.all这样的查找程序时覆盖ActiveRecord对我的日期时间字段所做的类型转换,但它似乎没有像我想象的那样工作。我期待着覆盖以返回datetime_before_type_cast,就像我在底部示例中直接访问字段时一样。

在我的模型中,我有我认为会覆盖属性的内容:

def datetime
  self.datetime_before_type_cast
end

SomeModel.first
#<SomeModel datetime: "2010-01-20 12:00:00"> #shouldn't it be "2010-01-20 12:00:00.123"?

SomeModel.first.datetime 
"2010-01-20 12:00:00.123"

2 个答案:

答案 0 :(得分:0)

这是我发现完成我想要做的事情的一种方式,虽然看起来似乎必须有更直接的方式。

此外,我应该补充说,数据正在我的控制器中呈现为xml,所以这似乎很适合。

def datetime
  self.datetime_before_type_cast # => 2010-01-20 12:00:00.123
end

#override to_xml, excluding the datetime field and replacing with the method of the same name
def to_xml(options = {})
  super(:methods => [:datetime], :except => :datetime)
end

SomeModel.first.to_xml

<?xml version="1.0" encoding="UTF-8"?>
...
<datetime>2010-01-20 12:00:00.123</datetime>
...

答案 1 :(得分:0)

下面假设Rails 3.x.

请记住

>> SomeModel.first
=> #<SomeModel datetime: "2010-01-20 12:00:00"> #shouldn't it be "2010-01-20 12:00:00.123"?

>> SomeModel.first.datetime
=> "2010-01-20 12:00:00.123"

将在Rails控制台中显示不同的输出,因为控制台将在语句的结果上调用#inspect。

>> SomeModel.first

实际上会显示

>> SomeModel.first.inspect

内部调用#attribute_for_inspect(name)(而不是调用重写的#datetime方法),而

>> SomeModel.first.datetime 

将调用重写的#datetime方法,其结果将在其上调用#inspect。

此外,如果您希望覆盖#inspect或#to_s方法以更改“datetime”的文本格式,请确保使用Ruby DateTime而不是时间,日期或其他日期/时间类字段。