How to cache tags with acts_as_taggable_on?

2020-03-20 06:17发布

问题:

I have model with tag context:

class Product < ActiveRecord::Base
  acts_as_taggable_on :categories
end

I'm trying to initialize tags caching:

class AddCachedCategoryListToProducts < ActiveRecord::Migration
  def self.up
    add_column :products,  :cached_category_list, :string
    Product.reset_column_information
    products = Product.all
    products.each { |p| p.save_cached_tag_list }
  end
end

But cached_category_list does not initializing. What I'm doing wrong? Does anybody can use caching with this gem (my version is 2.0.6)?

回答1:

If you are using this in combination with owned tags, that might be the problem. Looking at the code of the gem, it seems that the caching of owned tags isn't support

Hope this helps,

Best, J



回答2:

Well, today I had the same problem. I finally solved it, and my migration cached the desired tags. The problem with your migration was two-fold:

  1. The ActsAsTaggable code which sets up caching needs to run again after the column information is reset. Otherwise, the caching methods are not created (see https://github.com/mbleigh/acts-as-taggable-on/blob/v2.0.6/lib/acts_as_taggable_on/acts_as_taggable_on/cache.rb)

  2. The method you are calling, save_cached_tag_list, does NOT automatically save the record, as it is installed as a before_save hook, and it doesn't want to create an infinite loop. So you must call save.

So, try replacing your migration with the following, and it should work:

class AddCachedCategoryListToProducts < ActiveRecord::Migration
  def self.up
    add_column :products,  :cached_category_list, :string
    Product.reset_column_information
    # next line makes ActsAsTaggableOn see the new column and create cache methods
    ActsAsTaggableOn::Taggable::Cache.included(Product)
    Product.find_each(:batch_size => 1000) do |p|
      p.category_list # it seems you need to do this first to generate the list
      p.save! # you were missing the save line!
    end    
  end
end

That should do it.