acts_as_paranoid and counter_cache
July 27th, 2008
Counter caches in RoR eliminate the need to issue an sql query to determine the size of an associated collection. Using counter cache is quite simple. Here’s an example:
class Author < ActiveRecord::Base
has_many :books
end
class Book < ActiveRecord::Base
belongs_to :author, :counter_cache => true
end
add_column :authors, :books_count, :integer
Author.first.books.count # gets the value from the books_count column,
# rather than doing an sql count
There’s a problem if you use this alongside acts_as_paranoid. AAP is a plugin that provides ‘soft delete’ functionality. In order to achieve this, AAP overrides AR finder methods to check the ‘deleted_at’ column to determine if a record has been ‘deleted’. Due to a condition placed on the count (counting only undeleted objects), the counter cache is not used and instead an sql statement is issued.
class Author < ActiveRecord::Base
has_many :books
end
class Book < ActiveRecord::Base
acts_as_paranoid
belongs_to :author, :counter_cache => true
end
Author.first.books.count # SELECT count(*) AS count_all FROM `books`
# WHERE (`books`.author_id = 11524) AND
# (`books`.deleted_at IS NULL OR
# `books`.deleted_at > '2008-07-27 13:27:22')
Deleting an object from a ‘paranoid’ collection will still do the right thing (decrement the counter cache), making this easy to fix. You just have to add your own count method for the collection.
class Author < ActiveRecord::Base
has_many :books do
def count
books_count
end
end
end
Author.first.books.count # calls the count method, returning
# the books counter
This is also published on Learnhub



Sorry, comments are closed for this article.