0

I am using the counter_culture gem to cache my counts. Here are the models:

User model

has_many :memberships, dependent: :destroy

Membership model

has_many :authorables, dependent: :destroy
has_many :posts, through: :authorables

Post model

has_many :authorables, dependent: :destroy
has_many :authors, through: :authorables, source: :membership

Authorable model

belongs_to :membership
belongs_to :post

counter_culture :post, column_name: "authors_count"

As you can see, I am caching the authors_count on the post model.

When I update the post, post.update(authors: [membership]) the counter increments by 1, but when I try and remove the authors post.update(authors: []), the counter does not decrement.

Is there a way to fix it?

Abeid Ahmed
  • 315
  • 1
  • 5
  • 15
  • With the code unchanged, if I do `post.authors.find(1).destroy`, the `counter_cache` works as expected. But I do not understand why `post.update(authors: [])` does not work. – Abeid Ahmed Feb 09 '21 at 06:25

1 Answers1

1

Short answer is no. You cannot use post.update(authors: []) and trigger callbacks.

counter_culture gem that you provided builds its functionality on top of rails callbacks execution, I pointed in that url code which does it.

post.update(authors: []) this code doesn't trigger ActiveRecord callbacks.
Neither this one post.authors.find(1).delete.

So in order to trigger your callbacks and update counter_cache column, you will need to write some function that will resolve authors and trigger destroy

Consider this

some_conditions = { id: [1,2,3] }

post.authors.where(some_conditions).each(&:destroy)

For further reading you refer to this well-described answer about ActiveRecord callbacks

zhisme
  • 2,368
  • 2
  • 19
  • 28
  • 1
    Yes, this answer is correct. I created a method that runs when the number of authors persisted to the post does not match the number of authors to be persisted with the update action and it works as expected now. – Abeid Ahmed Feb 09 '21 at 16:23