有一个典型的博客应用程序。每个用户都有很多帖子。每个帖子都有很多标签。 我正在按照updated_at对每个帖子进行排序,以便最新更新的帖子显示在最顶层。例如,如果我更新帖子的内容,帖子将会出现在顶部。但是,当我添加标签时也会发生这种情况,因为标签已连接到相应的帖子。
我只希望内容更新更改updated_at字段。我不希望更新帖子的updated_at因为我添加了标签。有没有办法做到这一点?或者任何其他方式来实现这样的目标?谢谢!
答案 0 :(得分:4)
我想到了两种方法:
请勿将:updated_at
用于您目的。而是创建一个新列,例如:post_updated_at
,并在每个要使帖子移动到顶部的保存上手动更新。 Rails为此提供了一个方便的模型:
mypost.touch :post_updated_at
当您更新列并希望: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保存的属性),但前提是存在非忽略的属性。