Rails保存记录而不更新时间戳

Rails的save和update方法默认都会将updated_at更新为当前时间,并且不允许手动设置,但是有些情况下,我们可能希望只更新记录的某个字段,而不希望updated_at被更新,比如显示帖子的时候增加帖子的查看次数,这可以通过设置model的record_timestamps属性实现:

Post.record_timestamps=false

但是因为record_timestamps是一个类变量,因此改变这个值会影响到所有Post的保存,如果在同一时间有用户确实修改了Post的内容或者标题,updated_at也将不会更新。

Neeraj在这篇帖子里提供了一个方法,只修改当前对象的record_timestamps属性,在保存完后再进行恢复:

module ActiveRecord
  class Base
    def save_without_timestamping
      class << self
        def record_timestamps; false; end
      end
      save
      class << self
        def record_timestamps; super ; end
      end
    end
  end
end

这段代码将打开当前对象的metaclass,并为当前对象定义一个record_timestamps方法来覆盖全局的设置,你可以将这段代码放到initializer中,然后在不需要更新时间戳的时候调用save_without_timestamping来更新记录,就像下面这样:


post = Post.find(:id)
post.view_count += 1
post.save_without_timestamping

上面一个实现是通过super方法恢复record_timestamps设置的,Neeraj还提供了一个使用remove_method的版本,我个人更喜欢这个版本:


module ActiveRecord
  class Base
    def save_without_timestamping
      class << self
        def record_timestamps; false; end
      end
      save
      class << self
        remove_method :record_timestamps
      end
    end
  end
end

This entry was posted in 其它. Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.
  • http://ilstar.blogbus.com 星情

    谢谢博主,正用到这个功能,呵呵

    不过博主这个方法无论保存成功与否,都没有返回值状态啊,设个变量保存save的状态,再返回应该会好些

无觅相关文章插件,快速提升流量