Ruby on rails 如何更新单个属性而不触及更新的_at属性?

Ruby on rails 如何更新单个属性而不触及更新的_at属性?,ruby-on-rails,ruby,ruby-on-rails-3,Ruby On Rails,Ruby,Ruby On Rails 3,我怎样才能做到这一点 尝试创建2个方法,称为 def disable_timestamps ActiveRecord::Base.record_timestamps = false end def enable_timestamps ActiveRecord::Base.record_timestamps = true end 以及更新方法本身: def increment_pagehit update_attribute(:pagehit, pagehit+1) end 使用

我怎样才能做到这一点

尝试创建2个方法,称为

def disable_timestamps
  ActiveRecord::Base.record_timestamps = false
end

def enable_timestamps
  ActiveRecord::Base.record_timestamps = true
end
以及更新方法本身:

def increment_pagehit
  update_attribute(:pagehit, pagehit+1)
end
使用回调打开和关闭时间戳,如:

before_update :disable_timestamps, :only => :increment_pagehit
after_update :enable_timestamps, :only => :increment_pagehit
但它不会更新任何内容,甚至不会更新所需的属性(pagehit)

有什么建议吗?我不想为了计算页面点击率而创建另一个表。

或者更接近你的问题:


如果您只想增加一个计数器,我会使用
增量计数器
方法:

ModelName.increment_counter :pagehit, id

作为
update\u属性
的替代方法,在Rails 3.1+中,您可以使用
update\u列

update\u属性
跳过验证,但将在处触摸
updated\u并执行回调

update\u列
跳过验证,不在
处触摸
updated\u,也不执行回调

因此,
update\u列
是一个很好的选择,如果您不想影响
上的
updated\u并且不需要回调

有关更多信息,请参阅

还要注意,
update\u列
将更新内存模型中属性的值,并且不会将其标记为脏。例如:

p = Person.new(:name => "Nathan")
p.save
p.update_column(:name, "Andrew")
p.name == "Andrew" # True
p.name_changed? # False

为了避免麻烦,您也可以为此使用ModelName.update\u all:

def increment_pagehit
  self.class.update_all({ pagehit: pagehit+1 }, { id: id })
end

这也不会触及记录上的时间戳。

这样做不是一个好主意:

self.class.update_all({ pagehit: pagehit+1 }, { id: id })
应该是

self.class.update_all("pagehit = pagehit + 1", { id: id })

原因是,如果两个请求是并行的,那么在第一个版本中,两个请求都将使用相同的数字更新pagehits,因为它使用保存在Ruby内存中的数字。第二个选项使用sql server将该数字增加1,如果其中两个查询同时出现,服务器将逐个处理它们,并以正确的页面点击数结束。

如果精度不是很重要,并且您不希望代码运行多次,您可以尝试更改保存在数据库中的
updated_at
值,如下所示:

u = User.first
u.name = "Alex 2" # make some changes...
u.updated_at = u.updated_at + 0.000001.second # alter updated_at
u.save

因此Rails实际上会尝试保存相同的值,而不是用
时间来替换它。现在,您还有and(以及它们的bang版本),它们不会在
处更改
updated\u,不会触发验证回调,并且显然对计数器/整数很方便。

尝试使用
update\u属性!(:pagehit=>pagehit+1)
并查看是否有任何错误。顺便说一句,您是在这里错误地粘贴了两次
def disable_timestamps
,还是您的代码中的时间戳相同?可能是重复的,我想增加计数器,但不更改更新的_at值。这很有效,Rails 3中有一种新方法。我注意到的一件事是,计数器在页面视图之后递增。@lulalala如果要反映新计数,必须将对象重新加载到。示例:
object.reload
Nice!谢谢你提供的信息!;)与
update\u列
等价的Mongoid是
set
,如
person.set(:name,'Andrew')