How to implement Counter Cache in Rails?

I have a message controller and a comment controller. Post has a lot of comments, and the comments belong to Post. The node is associated with the counter_cache parameter, included as such:

#Inside post.rb has_many :comments #Inside comment.rb belongs_to :post, :counter_cache => true 

I have a comments_count column in my posts table, which is zero by default:

 add_column :posts, :comments_count, :integer, :default => 0 

In the create action of my comment controller, I have the following code:

 def create @posts = Post.find(params[:post_id]) @comment = @post.comments.build(params[:comment]) if @comment.save redirect_to root else render :action => 'new' end end 

My problem: when @comment.save , I get the following error:

 ArgumentError in CommentsController#create wrong number of arguments (2 for 0) 

Removing :counter_cache => true from comment.rb completely solves the problem, so I assume this is the cause of this undefined error. What am I missing here? How can I save my comment and still have the rails take care of my counter_cache for my message?

Thanks!


Update - attached application trace:

 /Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/base.rb:987:in `update_all' /Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/base.rb:987:in `update_counters_without_lock' /Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/locking/optimistic.rb:176:in `update_counters' /Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/base.rb:1006:in `increment_counter' /Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/associations.rb:1367:in `belongs_to_counter_cache_after_create_for_feed_entry' /Library/Ruby/Gems/1.8/gems/activesupport-2.3.8/lib/active_support/callbacks.rb:178:in `send' /Library/Ruby/Gems/1.8/gems/activesupport-2.3.8/lib/active_support/callbacks.rb:178:in `evaluate_method' /Library/Ruby/Gems/1.8/gems/activesupport-2.3.8/lib/active_support/callbacks.rb:166:in `call' /Library/Ruby/Gems/1.8/gems/activesupport-2.3.8/lib/active_support/callbacks.rb:93:in `run' /Library/Ruby/Gems/1.8/gems/activesupport-2.3.8/lib/active_support/callbacks.rb:92:in `each' /Library/Ruby/Gems/1.8/gems/activesupport-2.3.8/lib/active_support/callbacks.rb:92:in `send' /Library/Ruby/Gems/1.8/gems/activesupport-2.3.8/lib/active_support/callbacks.rb:92:in `run' /Library/Ruby/Gems/1.8/gems/activesupport-2.3.8/lib/active_support/callbacks.rb:276:in `run_callbacks' /Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/callbacks.rb:344:in `callback' /Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/callbacks.rb:267:in `create' /Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/base.rb:2915:in `create_or_update_without_callbacks' /Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/callbacks.rb:250:in `create_or_update' /Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/base.rb:2573:in `save_without_validation' /Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/validations.rb:1090:in `save_without_dirty' /Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/dirty.rb:79:in `save_without_transactions' /Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/transactions.rb:229:in `send' /Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/transactions.rb:229:in `with_transaction_returning_status' /Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/connection_adapters/abstract/database_statements.rb:136:in `transaction' /Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/transactions.rb:182:in `transaction' /Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/transactions.rb:228:in `with_transaction_returning_status' /Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/transactions.rb:196:in `save' /Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/transactions.rb:208:in `rollback_active_record_state!' /Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/transactions.rb:196:in `save' /Users/yuval/Sites/rails/blog/app/controllers/comments_controller.rb:6:in `create' /Library/Ruby/Gems/1.8/gems/actionpack-2.3.8/lib/action_controller/base.rb:1331:in `send' /Library/Ruby/Gems/1.8/gems/actionpack-2.3.8/lib/action_controller/base.rb:1331:in `perform_action_without_filters' /Library/Ruby/Gems/1.8/gems/actionpack-2.3.8/lib/action_controller/filters.rb:617:in `call_filters' /Library/Ruby/Gems/1.8/gems/actionpack-2.3.8/lib/action_controller/filters.rb:610:in `perform_action_without_benchmark' /Library/Ruby/Gems/1.8/gems/actionpack-2.3.8/lib/action_controller/benchmarking.rb:68:in `perform_action_without_rescue' /Library/Ruby/Gems/1.8/gems/activesupport-2.3.8/lib/active_support/core_ext/benchmark.rb:17:in `ms' /Library/Ruby/Gems/1.8/gems/activesupport-2.3.8/lib/active_support/core_ext/benchmark.rb:17:in `ms' /Library/Ruby/Gems/1.8/gems/actionpack-2.3.8/lib/action_controller/benchmarking.rb:68:in `perform_action_without_rescue' /Library/Ruby/Gems/1.8/gems/actionpack-2.3.8/lib/action_controller/rescue.rb:160:in `perform_action_without_flash' /Library/Ruby/Gems/1.8/gems/actionpack-2.3.8/lib/action_controller/flash.rb:151:in `perform_action' /Library/Ruby/Gems/1.8/gems/actionpack-2.3.8/lib/action_controller/base.rb:532:in `send' /Library/Ruby/Gems/1.8/gems/actionpack-2.3.8/lib/action_controller/base.rb:532:in `process_without_filters' /Library/Ruby/Gems/1.8/gems/actionpack-2.3.8/lib/action_controller/filters.rb:606:in `process' /Library/Ruby/Gems/1.8/gems/actionpack-2.3.8/lib/action_controller/base.rb:391:in `process' /Library/Ruby/Gems/1.8/gems/actionpack-2.3.8/lib/action_controller/base.rb:386:in `call' /Library/Ruby/Gems/1.8/gems/actionpack-2.3.8/lib/action_controller/routing/route_set.rb:438:in `call' 

Note that the only line that should not work directly with the Rails framework is this:

 /Users/yuval/Sites/rails/blog/app/controllers/comments_controller.rb:6:in `create' 

Line 6 is as follows:

 if @comment.save 

EDIT 2: @posts / @post is a typo at my end when writing a simplified example for StackOverflow, my actual application has no error.

Checking @comment , it seems completely true - it brings back exactly what I expect - a new instance of the comment with any information that I passed to it using build . It only explodes when the save method is called on it.

Thanks for all the suggestions. Any other ideas?

+4
source share
3 answers

I ran a sample rails application with your code and it all worked fine for me.

I would suggest debugging a little more, as hurikhan77 suggests and see if this is just the @ posts / @ post problem that suggested.

Also, try creating a post and comment in the console with very simple content to see if it works.

 $ ruby script/console # add whatever fields are necessary to create > @p = Post.create(:title => "TestPost1") # => #<Post id: 3, ... # again, add whatever is necessary to create > @c = @p.comments.create(:comment => "TestComment1") # => #<Comment id: 8, ... > Post.find(:last).comments_count # => 1 

See what it makes you.

/ JP

+9
source

It may be completely off-sign, but are you using @posts and then @post?

+2
source

ArgumentError in CommentsController # create

wrong number of arguments (2 to 0)

You get this error because @comment is not the object you expect. Try debugging this by inserting:

 logger.debug @comment.inspect 

You will see something unexpected, and it should raise at least an eyebrow. This should be the clou that you assigned Post.find(...) to @posts , but later tried working with @post .

+2
source

Source: https://habr.com/ru/post/1311593/


All Articles