实例公共方法
decrement_counter(counter_name, id, by: 1, touch: nil) 链接
通过直接 SQL 更新将数字字段减少一。
此方法与 increment_counter
的工作方式相同,但会将列值减少 1,而不是增加它。
参数
-
counter_name
- 应减少的字段的名称。 -
id
- 应减少的对象的 id 或 id 数组。 -
:by
- 减少值的量。默认为1
。 -
:touch
- 更新时触及时间戳列。传递true
以触及updated_at
和/或updated_on
。传递一个符号以触及该列或一个符号数组以仅触及那些列。
示例
# Decrement the posts_count column for the record with an id of 5
DiscussionBoard.decrement_counter(:posts_count, 5)
# Decrement the posts_count column for the record with an id of 5
by a specific amount.
DiscussionBoard.decrement_counter(:posts_count, 5, by: 3)
# Decrement the posts_count column for the record with an id of 5
# and update the updated_at value.
DiscussionBoard.decrement_counter(:posts_count, 5, touch: true)
来源:显示 | 在 GitHub 上
# File activerecord/lib/active_record/counter_cache.rb, line 176 def decrement_counter(counter_name, id, by: 1, touch: nil) update_counters(id, counter_name => -by, touch: touch) end
increment_counter(counter_name, id, by: 1, touch: nil) 链接
通过直接 SQL 更新将数字字段增加一。
此方法主要用于维护用于存储聚合值的 counter_cache 列。例如,DiscussionBoard
可能缓存 posts_count 和 comments_count,以避免在每次显示时运行 SQL 查询来计算帖子和评论的数量。
参数
-
counter_name
- 应增加的字段的名称。 -
id
- 应增加的对象的 id 或 id 数组。 -
:by
- 增量值。默认为1
。 -
:touch
- 更新时触及时间戳列。传递true
以触及updated_at
和/或updated_on
。传递一个符号以触及该列或一个符号数组以仅触及那些列。
示例
# Increment the posts_count column for the record with an id of 5
DiscussionBoard.increment_counter(:posts_count, 5)
# Increment the posts_count column for the record with an id of 5
# by a specific amount.
DiscussionBoard.increment_counter(:posts_count, 5, by: 3)
# Increment the posts_count column for the record with an id of 5
# and update the updated_at value.
DiscussionBoard.increment_counter(:posts_count, 5, touch: true)
来源:显示 | 在 GitHub 上
# File activerecord/lib/active_record/counter_cache.rb, line 146 def increment_counter(counter_name, id, by: 1, touch: nil) update_counters(id, counter_name => by, touch: touch) end
reset_counters(id, *counters, touch: nil) 链接
使用 SQL 计数查询将一个或多个计数器缓存重置为其正确值。当添加新的计数器缓存时,或者计数器已损坏或直接通过 SQL 修改时,此功能非常有用。
参数
-
id
- 要重置计数器的对象的 ID。 -
counters
- 要重置的一个或多个关联计数器。可以给出关联名称或计数器名称。 -
:touch
- 更新时触及时间戳列。传递true
以触及updated_at
和/或updated_on
。传递一个符号以触及该列或一个符号数组以仅触及那些列。
示例
# For the Post with id #1, reset the comments_count
Post.reset_counters(1, :comments)
# Like above, but also touch the +updated_at+ and/or +updated_on+
# attributes.
Post.reset_counters(1, :comments, touch: true)
来源:显示 | 在 GitHub 上
# File activerecord/lib/active_record/counter_cache.rb, line 33 def reset_counters(id, *counters, touch: nil) object = find(id) updates = {} counters.each do |counter_association| has_many_association = _reflect_on_association(counter_association) unless has_many_association has_many = reflect_on_all_associations(:has_many) has_many_association = has_many.find { |association| association.counter_cache_column && association.counter_cache_column.to_sym == counter_association.to_sym } counter_association = has_many_association.plural_name if has_many_association end raise ArgumentError, "'#{name}' has no association called '#{counter_association}'" unless has_many_association if has_many_association.is_a? ActiveRecord::Reflection::ThroughReflection has_many_association = has_many_association.through_reflection end foreign_key = has_many_association.foreign_key.to_s child_class = has_many_association.klass reflection = child_class._reflections.values.find { |e| e.belongs_to? && e.foreign_key.to_s == foreign_key && e.options[:counter_cache].present? } counter_name = reflection.counter_cache_column count_was = object.send(counter_name) count = object.send(counter_association).count(:all) updates[counter_name] = count if count != count_was end if touch names = touch if touch != true names = Array.wrap(names) options = names.extract_options! touch_updates = touch_attributes_with_time(*names, **options) updates.merge!(touch_updates) end unscoped.where(primary_key => object.id).update_all(updates) if updates.any? true end
update_counters(id, counters) 链接
一个通用的“计数器更新器”实现,主要用于 increment_counter
和 decrement_counter
,但也可以单独使用。它只是对具有给定 ID 的记录执行直接 SQL 更新,通过对应值给出的量更改给定的计数器哈希
参数
-
id
- 要更新计数器的对象的 ID 或 ID 数组。 -
counters
- 一个Hash
,其中包含要更新的字段的名称作为键,以及按值更新字段的量。 -
:touch
选项 - 更新时触碰时间戳列。如果传递属性名称,则会与 updated_at/on 属性一起更新。
示例
# For the Post with id of 5, decrement the comments_count by 1, and
# increment the actions_count by 1
Post.update_counters 5, comments_count: -1, actions_count: 1
# Executes the following SQL:
# UPDATE posts
# SET comments_count = COALESCE(comments_count, 0) - 1,
# actions_count = COALESCE(actions_count, 0) + 1
# WHERE id = 5
# For the Posts with id of 10 and 15, increment the comments_count by 1
Post.update_counters [10, 15], comments_count: 1
# Executes the following SQL:
# UPDATE posts
# SET comments_count = COALESCE(comments_count, 0) + 1
# WHERE id IN (10, 15)
# For the Posts with id of 10 and 15, increment the comments_count by 1
# and update the updated_at value for each counter.
Post.update_counters [10, 15], comments_count: 1, touch: true
# Executes the following SQL:
# UPDATE posts
# SET comments_count = COALESCE(comments_count, 0) + 1,
# `updated_at` = '2016-10-13T09:59:23-05:00'
# WHERE id IN (10, 15)
来源:显示 | 在 GitHub 上
# File activerecord/lib/active_record/counter_cache.rb, line 114 def update_counters(id, counters) unscoped.where!(primary_key => id).update_counters(counters) end