I wasted an entire day yesterday on :counter_cache => true
. (Why was it wasted? Because I didn't need a counter cache yesterday, but knew that I would need it in a few weeks or months...progress versus perfection rears its ugly head again.)
Anyhow the problem ultimately had nothing to do with counter caching, but the error message didn't help too much, and there wasn't much in Google about the error message, so I spent a lot of time looking for the problem in the wrong place. Hopefully this post will help others in the future if you're getting this error message:
NoMethodError in Document content templateController#create
undefined method `increment_counter' for Class:Class
Yesterday I was creating entities called
DocumentTemplate
and DocumentContentTemplate
:class DocumentTemplate < ActiveRecord::Base
has_many :DocumentContentTemplates
end
class DocumentContentTemplate < ActiveRecord::Base
belongs_to :DocumentTemplate
end
Then, I ran a quick
script/generate scaffold
on both of these, and modified the _form.rhmtl
for DocumentContentTemplate
in order to add the association to DocumentTemplate
. Everything is working fine.Next, I decide that I'm going to need a counter cache on the
DocumentTemplate
, so I modify the DocumentContentTemplate
model and added the document_content_templates_count
column to the document_templates
table via migration:class DocumentContentTemplate < ActiveRecord::Base
belongs_to :DocumentTemplate, :counter_cache => true
end
Now, when I create a new
DocumentContentTemplate
the method DocumentContentTemplate#create
should automatically increment the document_content_templates_count
column in the document_templates
table. But, when I submit the form that calls the create method I get this error:NoMethodError in Document content templateController#create
undefined method `increment_counter' for Class:Class
I spent hours debugging and investigating all the things related to counter cache, but it turns out that wasn't the problem. Go way back to the has_many and belongs_to declarations:
has_many :DocumentContentTemplates
belongs_to :DocumentTemplate
which, if you look carefully, should really be:
has_many :document_content_templates
belongs_to :document_template
So, if you're seeing that error, that's how to fix it. But, this raises two issues that I want to bring up:
1. My understanding is that the camel-case of a class name is supposed to be used when referring to the class, not an instance of it. For example, camelcase is used in a class definition or when the class is being used:
class DocumentTemplate < ActiveRecord::Base
DocumentTemplate.find(:all)
With that in mind, aren't the has_* and belongs_to methods referring to classes? Why don't they use the camelcase?
2. Regardless of the answer to #1, why does Rails handle this error gracefully? Why does
has_*|belongs_to :ClassName
not throw an error when it should be has_*|belongs :class_name
?
No comments:
Post a Comment