Spec-Zone.ru › Ruby on Rails 4.1

модуль ActiveRecord::CounterCache::ClassMethods

Публичные методы экземпляров

decrement_counter(counter_name, id) Показать исходный код

Уменьшает числовое поле на единицу с помощью прямого обновления SQL.

Этот метод работает так же, как #increment_counter, но уменьшает значение столбца на 1 вместо увеличения.

Параметры

  • counter_name - Имя поля, которое нужно уменьшить.

  • id - Идентификатор объекта, который нужно уменьшить, или массив идентификаторов.

Примеры

# Decrement the post_count column for the record with an id of 5
DiscussionBoard.decrement_counter(:post_count, 5)
# File activerecord/lib/active_record/counter_cache.rb, line 116
def decrement_counter(counter_name, id)
  update_counters(id, counter_name => -1)
end
increment_counter(counter_name, id) Показать исходный код

Увеличивает числовое поле на единицу с помощью прямого обновления SQL.

Этот метод в основном используется для поддержания счетчиков counter_cache, которые используются для хранения агрегированных значений. Например, DiscussionBoard может кэшировать posts_count и comments_count, чтобы избежать выполнения запроса SQL для расчета количества сообщений и комментариев каждый раз, когда он отображается.

Параметры

  • counter_name - Имя поля, которое нужно увеличить.

  • id - Идентификатор объекта, который нужно увеличить, или массив идентификаторов.

Примеры

# Increment the post_count column for the record with an id of 5
DiscussionBoard.increment_counter(:post_count, 5)
# File activerecord/lib/active_record/counter_cache.rb, line 98
def increment_counter(counter_name, id)
  update_counters(id, counter_name => 1)
end
reset_counters(id, *counters) Показать исходный код

Сбрасывает один или несколько счетчиков counter_cache до правильного значения с помощью запроса подсчета SQL. Это полезно при добавлении новых счетчиков counter_cache или если счетчик был поврежден или изменен напрямую с помощью SQL.

Параметры

  • id - Идентификатор объекта, для которого нужно сбросить счетчик.

  • counters - Один или несколько счетчиков ассоциации для сброса.

Примеры

# For Post with id #1 records reset the comments_count
Post.reset_counters(1, :comments)
# File activerecord/lib/active_record/counter_cache.rb, line 20
def reset_counters(id, *counters)
  object = find(id)
  counters.each do |association|
    has_many_association = _reflect_on_association(association.to_sym)
    raise ArgumentError, "'#{self.name}' has no association called '#{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| :belongs_to == e.macro && e.foreign_key.to_s == foreign_key && e.options[:counter_cache].present? }
    counter_name = reflection.counter_cache_column

    stmt = unscoped.where(arel_table[primary_key].eq(object.id)).arel.compile_update({
      arel_table[counter_name] => object.send(association).count(:all)
    }, primary_key)
    connection.update stmt
  end
  return true
end
update_counters(id, counters) Показать исходный код

Реализация универсального «обновления счетчика», предназначенная в первую очередь для использования методами #increment_counter и #decrement_counter, но также может быть полезной сама по себе. Она просто выполняет прямое обновление SQL для записи с заданным ID, изменяя заданный массив счетчиков на указанную величину:

Параметры

  • id - Идентификатор объекта, для которого нужно обновить счетчик, или массив идентификаторов.

  • counters - Массив, содержащий имена полей для обновления в качестве ключей и величину для обновления поля в качестве значений.

Примеры

# For the Post with id of 5, decrement the comment_count by 1, and
# increment the action_count by 1
Post.update_counters 5, comment_count: -1, action_count: 1
# Executes the following SQL:
# UPDATE posts
#    SET comment_count = COALESCE(comment_count, 0) - 1,
#        action_count = COALESCE(action_count, 0) + 1
#  WHERE id = 5

# For the Posts with id of 10 and 15, increment the comment_count by 1
Post.update_counters [10, 15], comment_count: 1
# Executes the following SQL:
# UPDATE posts
#    SET comment_count = COALESCE(comment_count, 0) + 1
#  WHERE id IN (10, 15)
# File activerecord/lib/active_record/counter_cache.rb, line 72
def update_counters(id, counters)
  updates = counters.map do |counter_name, value|
    operator = value < 0 ? '-' : '+'
    quoted_column = connection.quote_column_name(counter_name)
    "#{quoted_column} = COALESCE(#{quoted_column}, 0) #{operator} #{value.abs}"
  end

  unscoped.where(primary_key => id).update_all updates.join(', ')
end

© 2004–2016 David Heinemeier Hansson
Licensed under the MIT License.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API