【问题标题】:rails/ActiveRecord: How can I specify a different class for a particular attribute?rails/ActiveRecord:如何为特定属性指定不同的类?
【发布时间】:2011-03-03 01:33:43
【问题描述】:

在 Rails 3 中,我有一个数据库模型,它有一个 birthday 字段,类型为 date。出于各种原因(例如没有已知年份的日期),我希望它属于Date 以外的类,和/或将某些东西混入Date 类中,以便仅创建对象从这个属性。解决此问题的最佳方法是什么?

例如,假设我想做这样的事情:

class BirthDate < Date
  def to_s
    case year
    when 1 # if I store a date with a null year, it sets it to 1
      strftime("%m/%d")
    else
      super
    end
  end
end

那个类确实让我得到了我想要的行为(目前;我完全有可能在将来修改它),我可以让我的模型让我使用类似这样的东西来访问它:

class Person < ActiveRecord::Base
  def bday
    BirthDate.new(birthday.year, birthday.month, birthday.day)
  end
end

然后改变我的观点,使用生日而不是生日。不过,这似乎有点浪费(必须从已经创建的对象创建一个新对象——别介意Date 似乎没有“复制构造函数”类型的东西?(或者我只是在某个地方错过了它?)

无论如何,我认为 ActiveRecord 可能会提供如下所示的内容:

class Person < ActiveRecord::Base
  class_for :birthday => BirthDate
end

有类似的吗?我已经做了一堆谷歌搜索,并查看了许多文档,但没有找到它。不过不知道叫什么,

(也许是时候开始挖掘源代码了——我听说这是了解更多关于平台的好方法。再说一遍,some say otherwise ;))

【问题讨论】:

  • 为什么不在你的 Person 类上使用 mixin,替换你的“生日”访问器?

标签: ruby-on-rails ruby activerecord


【解决方案1】:

您可以手动覆盖该属性的 getter:

def birthday
  BirthDate.parse(birthday_before_type_cast)
end

【讨论】:

  • 这似乎适用于我正在做的事情,谢谢!不过,我确实有一个后续问题:(1) 这与BirthDate.parse(read_attribute(:birthday)) 有什么不同/更好/更差/什么? [旁注:我终于在源代码中查找了这个;它在lib/active_record/connection_adapters/abstract/schema_definitions.rb 中,与我的class_for 想法完全不同。]
  • read_attribute 方法实际上 type_casts 属性..所以日期对象将被初始化..但birthday_before_type_cast 将给出数据库中的日期字段..参见link
猜你喜欢
  • 1970-01-01
  • 2016-01-19
  • 1970-01-01
  • 2021-06-12
  • 1970-01-01
  • 1970-01-01
  • 2018-12-25
  • 1970-01-01
  • 2012-03-20
相关资源
最近更新 更多