如何更新模型" updated_at"字段仅用于列更新的子集?

时间:2012-04-05 22:20:53

标签: ruby-on-rails ruby-on-rails-3 activerecord data-modeling

有一个典型的博客应用程序。每个用户都有很多帖子。每个帖子都有很多标签。 我正在按照updated_at对每个帖子进行排序,以便最新更新的帖子显示在最顶层。例如,如果我更新帖子的内容,帖子将会出现在顶部。但是,当我添加标签时也会发生这种情况,因为标签已连接到相应的帖子。

我只希望内容更新更改updated_at字段。我不希望更新帖子的updated_at因为我添加了标签。有没有办法做到这一点?或者任何其他方式来实现这样的目标?谢谢!

2 个答案:

答案 0 :(得分:4)

我想到了两种方法:

  1. 请勿将:updated_at用于您目的。而是创建一个新列,例如:post_updated_at,并在每个要使帖子移动到顶部的保存上手动更新。 Rails为此提供了一个方便的模型:

    mypost.touch :post_updated_at
    
  2. 当您更新列并希望:updated_at保持不变时,请使用#update_column方法,该方法使用您提供的值直接更新数据库中的列。请注意,它会逐字地将值写入数据库,因此如果相关列是一个花哨的serialize列或类似列,您必须要聪明。

答案 1 :(得分:0)

此处是for(it=begin();it<end();it++)的替代品,可让您将黑名单列入“无聊”状态。属性,即那些不会触发时间戳更新的属性。它依赖于Rails 4+ save方法来在保存期间抑制回调方法(小心抑制那些)。

update_columns

实施说明:

上面的最后一行是常规保存。我最初尝试在没有检查的情况下进行保存,因为如果已经保存了已忽略的属性,则不会发生任何事情(因为# Here we configure attribs that won't trigger the timestamp update IGNORED_ATTRIBS = Set.new %w(reviewed_at view_count) # A "save" replacement def fussy_save # Calculate any ignored attributes that are pending a save all_changed_attribs = Set.new(self.changed_attributes.keys) ignored_changed_attribs = IGNORED_ATTRIBS.intersection all_changed_attribs # Save the ignored attributes without triggering updated_at if ignored_changed_attribs.present? self.update_columns self.attributes.slice(*ignored_changed_attribs) end # perform a normal save only if there are additional attributes present if !all_changed_attribs.subset?(IGNORED_ATTRIBS) save end end 什么都不做,并且如果没有保存attribs则不会更新时间戳) 。但我发现save实际上是Rails&#39;内部,权威,参考,不仅仅是开发人员的便利(不太令人惊讶:)。开始搞乱它感觉很危险,所以我只是执行检查,所有更改的属性都将保存在SQL中(包括刚刚由update_columns保存的属性),但前提是存在非忽略的属性。