简体   繁体   中英

How do I update a counter of an associated object before it is saved?

I have an attribute on my Node object called cached_comment_count where I need it to be updated whenever a new comment is created.

This is part of my create action in my CommentsController :

@node = Node.find(params[:node_id])
@comment = current_user.comments.new(comment_params)
@comment.node = @node
@node.cached_comment_count = @node.comments.count

However, this doesn't work because when I do @node.comments.count that just returns the current comments on the @node object before this new @comment is saved.

What does work is if I do:

@node.cached_comment_count += 1

The obvious issue with this is that it is simply just an increment of 1 - and doesn't feel complete. The best, most complete, way is to get the comments.count after this save has taken place.

But I don't want to end up in an infinite loop.

What's the best way to approach this?

Just consider counter_cache rails functionality. You can check what is it by old, but still good Ryan Bates railscast

you may use counter_cache

With this declaration, Rails will keep the cache value up to date, and then return that value in response to the size method

 in comment.rb
      ##should look something like this
      ##add this column in node table....comments_count
       belongs_to :node, counter_cache: true

by using @node.comments.size

Why don't you add after create hook inside your Comment model.

class Comment < ActiveRecord::Base
  after_create :increment_comment_cache

  private

  def increment_comment_cache
    self.node.update cached_comment_count: self.node.comments.count
  end
end

Then remove your logic from controller, remove lines

@comment.node = @node
@node.cached_comment_count = @node.comments.count

This way, you get very DRY way of updating cache count, from any place you create comment it will automaticaly update count for you

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM