Rails :counter_cache لا يقوم بتشغيل رد الاتصال after_update

StackOverflow https://stackoverflow.com/questions/9399408

  •  29-10-2019
  •  | 
  •  

سؤال

لذلك، لدي نماذج مجلد وFolderItem.

تحديث

# == Schema Information
#
# Table name: folders
#
#  id                 :integer         not null, primary key
#  name               :string(255)     not null
#  parent_folder_id   :integer
#  user_id            :integer         not null
#  folder_itens_count :integer         default(0)
#  created_at         :datetime
#  updated_at         :datetime
#

class Folder < ActiveRecord::Base
...

  belongs_to :parent_folder, :class_name => 'Folder'
  has_many :child_folders, :class_name => 'Folder', :foreign_key => :parent_folder_id
  has_many :folder_itens, :order => 'created_at DESC'

  after_update {
    update_parent_folder_itens_count
  }

  def update_parent_folder_itens_count
    parent_folder = self.parent_folder
    if self.folder_itens_count_changed? && parent_folder
      quant_changed = self.folder_itens_count - self.folder_itens_count_was
      parent_folder.increment(:folder_itens_count, quant_changed)
    end
  end
end

class FolderItem < ActiveRecord::Base
... 
  belongs_to :folder, :counter_cache => :folder_itens_count
end

أنا أستخدم counter_cache للاحتفاظ بعدد عناصر مجلد واحد.ولكن قد يكون المجلد هو الأصل لمجلد آخر، وأردت أن يحتوي المجلد الأصلي على مجموع ذاكرة التخزين المؤقت المضادة لكل العناصر التابعة له بالإضافة إلى ذاكرة التخزين المؤقت المضادة الخاصة به.

للقيام بذلك، حاولت وضع طريقة after_update للتخزين المؤقت للتغييرات التي تم إجراؤها في عمود counter_cache، ولكن بطريقة ما لا يتم استدعاء هذه الطريقة عند إنشاء FolderItem جديد.

هل كانت مفيدة؟

المحلول

سأفعل شيئا من هذا القبيل.

أضف بعض حقول عداد ذاكرة التخزين المؤقت إلى جدول المجلدات

$ rails g migration add_cache_counters_to_folders child_folders_count:integer \
                                                  folder_items_count:integer  \
                                                  total_items_count:integer   \
                                                  sum_of_children_count:integer

وكود روبي

class Folder < ActiveRecord::Base
  belongs_to :parent_folder, class_name: 'Folder', counter_cache: :child_folders_count
  has_many :child_folders, class_name: 'Folder', foreign_key: :parent_folder_id
  has_many :folder_items

  before_save :cache_counters

  # Direct descendants - files and items within this folder
  def total_items
    child_folders_count + folder_items_count
  end

  # All descendants - files and items within all the folders in this folder
  def sum_of_children
    folder_items_count + child_folders.map(&:sum_of_children).inject(:+)
  end

private
  def cache_counters
    self.total_items_count = total_items
    self.sum_of_children_count = sum_of_children
  end
end

class FolderItem < ActiveRecord::Base
  belongs_to :folder, counter_cache: true # folder_items_count
end

يرجى ملاحظة أن Folder#sum_of_children- الطريقة متكررة، لذلك بالنسبة لمجموعات البيانات الكبيرة قد تؤدي إلى إبطاء تطبيقك.قد ترغب في القيام بمزيد من سحر SQL لها، ولكن نظرًا لأن روبي خالصة، فهذا أقرب ما يمكن إلى الحل الجيد الذي يمكنني الحصول عليه.لقد رأيت أنك فعلت ذلك في الاتجاه المعاكس، وسيكون ذلك بطيئًا تمامًا كما تحتاج إلى التحديث من الأسفل إلى الأعلى أيضًا.(هذا من أعلى إلى أسفل)

لا أعرف إذا كان هذا هو ما تبحث عنه، ولكنه حل قابل للقراءة للتخزين المؤقت لعدد العناصر داخل المجلد.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top