【问题标题】:How to update a model's "updated_at" field only for a subset of column updates?如何仅为列更新的子集更新模型的“updated_at”字段?
【发布时间】:2012-04-19 16:15:24
【问题描述】:

有一个典型的博客应用程序。每个用户都有_many 个帖子。每个帖子都有_many标签。 我按 updated_at 对每个帖子进行排序,因此最近更新的帖子将显示在顶部。因此,例如,如果我更新帖子的内容,该帖子将出现在顶部。但是,当我只添加一个标签时也会发生这种情况,因为一个标签与其对应的帖子相连。

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

【问题讨论】:

  • 你能猴子补丁“updated_at=" 并且只有在某个标志被通过时才尊重它(设置支持源)? (我不使用 RoR,所以不知道何时/如何更新该字段。)
  • 您可以尝试在标签模型中将 touch 设置为 false,例如 belongs_to :post, :touch => false。也许这有帮助

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


【解决方案1】:

我想到了两种方法:

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

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

【讨论】:

  • 是的,想想看,这是有道理的:)
  • @michael 建议不要使用 :updated_at 的原因是什么......?
  • @SriVishnuTotakura:除了作为向用户呈现新更改数据的标准外,保留:updated_at 用于对行的任何直接或相关更改也很有用,例如增量搜索索引和故障排除。我通常更渴望增加更新:updated_at 的频率(例如has_many 关联的变化)而不是减少它。
【解决方案2】:

这是save 的替代品,它可以让您将“无聊”属性(即不触发时间戳更新的属性)列入黑名单。它依赖 Rails 4+ 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

实施说明:

上面的最后一行是常规保存。我最初尝试在不检查的情况下进行保存,因为如果已保存忽略的属性,则不会发生任何事情(因为 save 什么都不做,并且如果没有保存属性,则不会更新时间戳)。但我发现changed_attributes 实际上是 Rails 内部的、权威的、参考,而不仅仅是对开发人员的方便(不太令人惊讶:)。开始弄乱它感觉很危险,所以我只是执行检查,所有更改的属性都将保存在 SQL 中(包括刚刚由 update_columns 保存的属性),但前提是存在未忽略的属性。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-07
  • 2019-09-30
  • 2017-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-18
相关资源
最近更新 更多