Ruby on Rails 5.2 - ActiveRecord::CounterCache::ClassMethods

मॉड्यूल ActiveRecord :: CounterCache :: ClassMethods




ruby

मॉड्यूल ActiveRecord :: CounterCache :: ClassMethods

सार्वजनिक प्रवृत्ति के तरीके

decrement_counter (counter_name, id, touch: nil) स्रोत दिखाएं
# File activerecord/lib/active_record/counter_cache.rb, line 176
def decrement_counter(counter_name, id, touch: nil)
  update_counters(id, counter_name => -1, touch: touch)
end

एक प्रत्यक्ष SQL अद्यतन के माध्यम से एक के बाद एक संख्यात्मक क्षेत्र में कमी।

यह increment_counter के समान काम करता है, लेकिन इसे बढ़ाने के बजाय स्तंभ मान को 1 से कम कर देता है।

पैरामीटर

  • counter_name - उस फ़ील्ड का नाम जिसे घटाया जाना चाहिए।

  • id - ऑब्जेक्ट की आईडी जिसे डीआरआरएटेड किया जाना चाहिए या आईडी की एक सरणी।

  • :touch - अपडेट करते समय टाइमस्टैम्प कॉलम को टच करें। updated_at और / या updated_on को छूने के लिए true पास करें उस कॉलम को छूने के लिए एक प्रतीक पास करें या उन लोगों को छूने के लिए प्रतीकों की एक सरणी।

उदाहरण

# 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
# and update the updated_at value.
DiscussionBoard.decrement_counter(:posts_count, 5, touch: true)
increment_counter (counter_name, id, touch: nil) स्रोत दिखाएं
# File activerecord/lib/active_record/counter_cache.rb, line 151
def increment_counter(counter_name, id, touch: nil)
  update_counters(id, counter_name => 1, touch: touch)
end

एक प्रत्यक्ष SQL अद्यतन के माध्यम से एक के बाद एक संख्यात्मक क्षेत्र में वृद्धि।

इस पद्धति का उपयोग मुख्य रूप से काउंटर_ कैश कॉलम को बनाए रखने के लिए किया जाता है जो कुल मूल्यों को संग्रहीत करने के लिए उपयोग किया जाता है। उदाहरण के लिए, डिस्कशनबॉबर्ड पोस्ट_काउंट और कॉमेंट_काउंट को कैश कर सकता है। पोस्ट और टिप्पणियों की संख्या की गणना करने के लिए SQL क्वेरी चलाने से बचने के लिए, हर बार यह प्रदर्शित होता है।

पैरामीटर

  • counter_name - उस क्षेत्र का नाम जिसे बढ़ाना चाहिए।

  • id - उस वस्तु का आईडी जो बढ़ाना या आईडी की एक सरणी होनी चाहिए।

  • :touch - अपडेट करते समय टाइमस्टैम्प कॉलम को टच करें। updated_at और / या updated_on को छूने के लिए true पास करें उस कॉलम को छूने के लिए एक प्रतीक पास करें या उन लोगों को छूने के लिए प्रतीकों की एक सरणी।

उदाहरण

# 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
# and update the updated_at value.
DiscussionBoard.increment_counter(:posts_count, 5, touch: true)
reset_counters (id, * counters, touch: nil) स्रोत दिखाएँ
# File activerecord/lib/active_record/counter_cache.rb, line 29
def reset_counters(id, *counters, touch: nil)
  object = find(id)

  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

    updates = { counter_name => object.send(counter_association).count(:all) }

    if touch
      names = touch if touch != true
      updates.merge!(touch_attributes_with_time(*names))
    end

    unscoped.where(primary_key => object.id).update_all(updates)
  end

  true
end

SQL काउंट क्वेरी का उपयोग करके एक या अधिक काउंटर कैश को उनके सही मान पर रीसेट करता है। नए काउंटर कैश को जोड़ने पर यह उपयोगी है, या यदि काउंटर को SQL द्वारा सीधे दूषित या संशोधित किया गया है।

पैरामीटर

  • id - जिस ऑब्जेक्ट को आप रीसेट करना चाहते हैं, उसका आईडी।

  • counters - रीसेट करने के लिए एक या अधिक एसोसिएशन काउंटर। एसोसिएशन का नाम या काउंटर नाम दिया जा सकता है।

  • :touch - अपडेट करते समय टाइमस्टैम्प कॉलम को टच करें। updated_at और / या updated_on को छूने के लिए true पास करें उस कॉलम को छूने के लिए एक प्रतीक पास करें या उन लोगों को छूने के लिए प्रतीकों की एक सरणी।

उदाहरण

# 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)
update_counters (id, counters) शो सोर्स
# File activerecord/lib/active_record/counter_cache.rb, line 104
def update_counters(id, counters)
  touch = counters.delete(:touch)

  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

  if touch
    names = touch if touch != true
    touch_updates = touch_attributes_with_time(*names)
    updates << sanitize_sql_for_assignment(touch_updates) unless touch_updates.empty?
  end

  if id.is_a?(Relation) && self == id.klass
    relation = id
  else
    relation = unscoped.where!(primary_key => id)
  end

  relation.update_all updates.join(", ")
end

एक सामान्य "काउंटर अपडेटर" कार्यान्वयन, जिसका मुख्य रूप से उपयोग increment_counter और decrement_counter द्वारा किया जाना है, लेकिन जो अपने आप भी उपयोगी हो सकता है। यह बस दिए गए आईडी के साथ रिकॉर्ड के लिए एक सीधा SQL अपडेट करता है, जो संबंधित मूल्य द्वारा दी गई राशि से काउंटरों के दिए गए हैश को बदल देता है:

पैरामीटर

  • id - उस वस्तु की आईडी जो आप आईडी के काउंटर या सरणी पर अपडेट करना चाहते हैं।

  • counters - कुंजी के रूप में अद्यतन करने के लिए फ़ील्ड का नाम और मान के रूप में फ़ील्ड को अपडेट करने के लिए राशि सहित एक Hash

  • :touch विकल्प - अद्यतन करते समय टाइमस्टैम्प कॉलम स्पर्श करें। यदि विशेषता नाम पारित किए जाते हैं, तो उन्हें अपडेट किया गया है साथ ही update_at / विशेषताएँ पर।

उदाहरण

# 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)

# For the Posts with id of 10 and 15, increment the comment_count by 1
# and update the updated_at value for each counter.
Post.update_counters [10, 15], comment_count: 1, touch: true
# Executes the following SQL:
# UPDATE posts
#    SET comment_count = COALESCE(comment_count, 0) + 1,
#    `updated_at` = '2016-10-13T09:59:23-05:00'
#  WHERE id IN (10, 15)