【问题标题】:Virtual attributes from define_method generated methods in rails 2.3来自define_method的虚拟属性在rails 2.3中生成的方法
【发布时间】:2012-01-18 17:28:30
【问题描述】:

我有获取和设置虚拟属性的方法。实际上,他们在真实属性上设置了一个字符,正如这段代码 sn-p 应该解释的那样:

attr_accessible :picnic_on_sunday, :picnic_on_monday, :picnic_on_tuesday,
                :picnic_on_wednesday, :picnic_on_thursday, :picnic_on_friday,
                :picnic_on_saturday,

['sunday', 'monday', 'tuesday', 'wednesday', 'thursday',
  'friday', 'saturday'].each_with_index do |dayname, dayindex|
  define_method "picnic_on_#{dayname.downcase}".to_sym do
    picnic_weekdays[dayindex]=='1'
  end
  define_method "picnic_on_#{dayname.downcase}=" do |value|
    wdays = picnic_weekdays
    wdays[dayindex] = (value==true or value=='1') ? '1':'0'
    self.picnic_weekdays = wdays 
  end
end

picnic_weekdays 是方案中存在的真实属性。我的问题是,虽然生成的 getter/setter 在我进行更改时工作,x.picnic_on_monday = true 更改了x.picnic_weekdays 上的索引 1,但当我在模型上调用 save 时没有保存任何内容。仅当方法由define_method 生成时才会出现此行为。为什么会这样?如何使生成的虚拟属性起作用?谢谢你的解释。

【问题讨论】:

  • 如果您还没有添加 attr_accessible :picnic_weekdays 可能值得一试。
  • 是的,我已经尝试过了,结果相同。虽然我实际上以其他方式解决了这个问题,但我仍然对为什么这个构造不能像我预期的那样工作很感兴趣。谢谢你的建议!
  • 您正在实现一个位域,但代码中存在一些概念性错误。我个人不会自己这样做,而是使用插件。 github.com/xing/flag_shih_tzu 完全符合您的要求。它经过了良好的测试和良好的维护。
  • @baaij 感谢您的提示!值得一试。您指的是哪些概念错误?也许只是更具体地了解它们会给出答案。

标签: ruby-on-rails activerecord attributes ruby-on-rails-2


【解决方案1】:

您对picnic_weekdays 所做的更改不是持久的,因为您似乎已经破坏了 ActiveRecord 中跟踪已更改属性的内部逻辑!我的猜测是由于 Dirty 模块被修补到 ActiveRecord 中的方式。

您问题中的示例可以通过使用<attribute>_will_change! 方法告诉ActiveRecord 属性已更改来修复,如下所示:

define_method "picnic_on_#{dayname.downcase}=" do |value|
  wdays = picnic_weekdays
  wdays[dayindex] = (value==true or value=='1') ? '1':'0'
  self.picnic_weekdays = wdays 
  self.picnic_weekdays_will_change!
end

【讨论】:

  • 很好的解释,值得一试,听起来像是一个答案。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-18
  • 2011-03-11
  • 2013-01-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多