Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/52.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Rails:计数器\u缓存在\u更新回调后未触发_Ruby On Rails_Counter Cache - Fatal编程技术网

Ruby on rails Rails:计数器\u缓存在\u更新回调后未触发

Ruby on rails Rails:计数器\u缓存在\u更新回调后未触发,ruby-on-rails,counter-cache,Ruby On Rails,Counter Cache,所以,我有一个文件夹和一个文件夹项目模型 更新 # == Schema Information # # Table name: folders # # id :integer not null, primary key # name :string(255) not null # parent_folder_id :integer # user_id :integer

所以,我有一个文件夹和一个文件夹项目模型

更新

# == 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
#==架构信息
#
#表名称:文件夹
#
#id:整数不为空,主键
#名称:字符串(255)不为空
#父文件夹\u id:整数
#用户id:整数不为空
#文件夹计数:整数默认值(0)
#创建时间:datetime
#更新时间:datetime
#
类文件夹“文件夹”
有多个:子文件夹,:类名称=>'文件夹',:外键=>:父文件夹id
有多个:文件夹\u itens,:order=>“已在DESC创建”
更新后{
更新\u父\u文件夹\u itens\u计数
}
def更新\u父文件夹\u itens\u计数
父文件夹=self.parent\u文件夹
如果self.folder_itens_count_更改了&&父文件夹
quant\u changed=self.folder\u itens\u count-self.folder\u itens\u count\u已更改
父文件夹。增量(:文件夹计数,数量已更改)
结束
结束
结束
类FolderItem:文件夹\u itens\u计数
结束
我使用计数器缓存来保存单个文件夹的iTen数。但是一个文件夹可能是另一个文件夹的父文件夹,我希望父文件夹的所有子文件夹的计数器缓存加上它自己的计数器缓存之和


为此,我尝试在“计数器缓存”列中放置一个“更新后”方法来缓存所做的更改,但不知何故,在创建新的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
和Ruby代码

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
class文件夹
请注意,
Folder#sum_of_children
-方法是递归的,因此对于大型数据集,它可能会降低应用程序的速度。您可能想对它进行更多的SQL操作,但对于纯Ruby来说,这是我能得到的最好的解决方案。我看到你是用另一种方式来做的,这会很慢,因为你也需要从下到上进行更新。(这是自上而下的)


我不知道这是否是您想要的,但它是一个可读的解决方案,用于缓存文件夹中的项目数。

我会这样做

将一些缓存计数器字段添加到文件夹表

$ 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
和Ruby代码

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
class文件夹
请注意,
Folder#sum_of_children
-方法是递归的,因此对于大型数据集,它可能会降低应用程序的速度。您可能想对它进行更多的SQL操作,但对于纯Ruby来说,这是我能得到的最好的解决方案。我看到你是用另一种方式来做的,这会很慢,因为你也需要从下到上进行更新。(这是自上而下的)


不知道这是否是您正在寻找的,但它是一个可读的解决方案,用于缓存文件夹中的项目数。

一些实际代码来了解为什么不调用它会很好。比如FolderItem课程?这听起来像是您必须为之编写完整的自定义缓存代码,因为计数器缓存只针对Folder.has\u many:items。您正在做的是Folder.has_many:folders,它本身有许多文件夹。刚刚添加了代码。我仍然认为我所做的应该是可能的,但我认为它不起作用,因为计数器缓存的处理方式,我猜它就像一个嵌套的SQL,所以rails代码被忽略了。但我只是想确定一下,用一些实际的代码看看为什么不调用它会很好。比如FolderItem课程?这听起来像是您必须为之编写完整的自定义缓存代码,因为计数器缓存只针对Folder.has\u many:items。您正在做的是Folder.has_many:folders,它本身有许多文件夹。刚刚添加了代码。我仍然认为我所做的应该是可能的,但我认为它不起作用,因为计数器缓存的处理方式,我猜它就像一个嵌套的SQL,所以rails代码被忽略了。但我只是想确定一下。