如何正确使用datamapper回调(或挂钩)?

时间:2012-11-20 17:40:36

标签: ruby database callback sinatra datamapper

我尝试了以下内容:

class DataEntry
  include DataMapper::Resource
  property :id,         Serial,   :key => true
  property :some_data,    Text,   :length => 1000000
  property :created_at, DateTime

  after :save do |entry|
    if entry.created_at.strftime('%T') == "00:00:00"
      @new_datetime = ((entry.created_at.to_time+1)-3600).to_datetime
      entry.update!(:created_at => @new_datetime)
    end
    return true
  end
end

如果条目是00:00:00(小时:分钟:秒),这应该将条目保存的时间更改为00:00:01。我知道我的代码很脏(我正在学习ruby,datamapper等,我有点像菜鸟;)),但更糟糕的是:它对模型没有任何影响。它只是保存,好像我的钩子不存在。我做错了什么?

(也许重要的是:我在sinatra中使用它,所以我无法访问像n.hours等的rails助手!)

提前致谢! ;)

2 个答案:

答案 0 :(得分:2)

为什么使用after

我建议使用before来避免对对象进行双重操作。

使用self,您可以使用

省略多余的entry

,无需return true

另外,为什么实例变量?

before :save do
  if self.created_at.strftime('%T') == "00:00:00"
    self.created_at = ((self.created_at.to_time+1)-3600).to_datetime
  end
end

答案 1 :(得分:0)

如果其他人发现这一点,虽然接受的答案提供了一种解决方法,但是关于为什么“后”钩子没有触发的原始​​问题的答案可能是因为“after:save”钩子将会没有火,除非模型在调用保存时变脏!

因此;

m = MyModel.first
m.save #Hook will not fire
m.name = "Foo"
m.save #Hook will fire

数据映射器的小怪癖,通过这种方式做事可以提高性能,但可读性可以通过IMO发布。