Counter Cache for a column with conditions?

后端 未结 4 1618
旧时难觅i
旧时难觅i 2020-11-30 06:34

I am new to the concept of counter caching and with some astronomical load times on one of my app\'s main pages, I believe I need to get going on it.

Most of the coun

相关标签:
4条回答
  • 2020-11-30 07:08

    You should not use "counter_cache" but rather a custom column :

    rails g migration AddCompletedProjectsCountToEmployees completed_projects_count:integer
    

    (add , :default => 0 to the add_column line if you want)

    rake db:migrate
    

    then use callbacks

    class Project < ActiveRecord::Base
      belongs_to :employee
    
      after_save :refresh_employee_completed_projects_count
      after_destroy :refresh_employee_completed_projects_count
    
      def refresh_employee_completed_projects_count
        employee.refresh_completed_projects_count
      end
    end
    
    class Employee
      has_many :projects
    
      def refresh_completed_projects_count
        update(completed_projects_count:projects.where(completed:true).size)
      end
    end
    

    After adding the column, you should initialize in the console or in the migration file (in def up) :

    Employee.all.each &:refresh_completed_projects_count
    

    Then in your code, you should call employee.completed_projects_count in order to access it

    0 讨论(0)
  • 2020-11-30 07:13

    Check counter_culture gem:

    counter_culture :category, column_name: Proc.new {|project| project.complete? ? 'complete_count' : nil }
    
    0 讨论(0)
  • 2020-11-30 07:15

    Instead of update_counters i use update_all

    You don't need the Employee.reset_column_information line AND it's faster because you are doing a single database call

    Employee.update_all("projects_count = (
       SELECT COUNT(projects.id) FROM projects 
       WHERE projects.employee_id = employees.id AND projects.complete = 't')")
    
    0 讨论(0)
  • 2020-11-30 07:17

    With regards to the conditions with counter_cache, I would read this blog post.

    The one thing you should do is add the following to the migration file:

     add_column :employees, :projects_count, :integer, :default => 0, :null => false
    
     Employee.reset_column_information
    
     Employee.all.each do |e|
       Employee.update_counters e.id, :projects_count => e.projects.length
     end
    

    So you current projects count can get migrated to the new projects_count that are associated with each Employee object. After that, you should be good to go.

    0 讨论(0)
提交回复
热议问题