RoR: ActiveRecord, NoMethodError in models that are extended from AR
I have the following models set up:
class Qa::Base < ActiveRecord::Base
self.abstract_class = true
Qa::Base.establish_connection("qa_audit_#{RAILS_ENV}")
end
class Qa::ErrorType < Qa::Base set_table_name "error_types"
# Associations has_many :errors, :class_name => 'Qa::Error' has_many :evaluations, :class_name => 'Qa::Evaluation', :through => :errors # Validations validates_presence_of :content validates_uniqueness_of :content endBut when saving/validating a model I keep hitting the following NoMethodErrors:
NoMethodError (undefined method `add_on_blank' for #Class:0x23a3020):
Eg:
e = Qa::ErrorType.first
e.valid?
produces
NoMethodError: undefined method
add_on_blank' for #<Class:0x223eeb4>
from /opt/local/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/base.rb:1994:in
method_missing_without_pagin开发者_StackOverflow社区ate'
from /opt/local/lib/ruby/gems/1.8/gems/will_paginate-2.3.14/lib/will_paginate/finder.rb:170:in method_missing'
from /opt/local/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/associations/association_collection.rb:380:in
send'
from /opt/local/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/associations/association_collection.rb:380:in method_missing_without_paginate'
from /opt/local/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/base.rb:2178:in
with_scope'
from /opt/local/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/associations/association_proxy.rb:207:in send'
from /opt/local/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/associations/association_proxy.rb:207:in
with_scope'
from /opt/local/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/associations/association_collection.rb:376:in method_missing_without_paginate'
from /opt/local/lib/ruby/gems/1.8/gems/will_paginate-2.3.14/lib/will_paginate/finder.rb:170:in
method_missing'
from /opt/local/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/validations.rb:599:in validates_presence_of'
from /opt/local/lib/ruby/gems/1.8/gems/activesupport-2.3.8/lib/active_support/callbacks.rb:182:in
call'
from /opt/local/lib/ruby/gems/1.8/gems/activesupport-2.3.8/lib/active_support/callbacks.rb:182:in evaluate_method'
from /opt/local/lib/ruby/gems/1.8/gems/activesupport-2.3.8/lib/active_support/callbacks.rb:166:in
call'
from /opt/local/lib/ruby/gems/1.8/gems/activesupport-2.3.8/lib/active_support/callbacks.rb:90:in run'
from /opt/local/lib/ruby/gems/1.8/gems/activesupport-2.3.8/lib/active_support/callbacks.rb:90:in
each'
from /opt/local/lib/ruby/gems/1.8/gems/activesupport-2.3.8/lib/active_support/callbacks.rb:90:in send'
from /opt/local/lib/ruby/gems/1.8/gems/activesupport-2.3.8/lib/active_support/callbacks.rb:90:in
run'
from /opt/local/lib/ruby/gems/1.8/gems/activesupport-2.3.8/lib/active_support/callbacks.rb:276:in run_callbacks'
from /opt/local/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/validations.rb:1110:in
valid_without_callbacks?'
from /opt/local/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/callbacks.rb:315:in `valid?'
I have used the same code pattern elsewhere in the same application before and that portion still works fine (all the validations work as they are supposed to).
Can someone shed some light on what I am doing wrong.
Figured out what the problem was:
class Qa::ErrorType < Qa::Base
set_table_name "error_types"
# Associations
has_many :errors, :class_name => 'Qa::Error'
has_many :evaluations, :class_name => 'Qa::Evaluation', :through => :errors
# Validations
validates_presence_of :content
validates_uniqueness_of :content
end
This declaration overrides the errors association/object that ActiveRecord provides hence we loose all validation functionality provided by ActiveRecord::Validations. Renaming the association to a more specific thing resolves the problem.
Correct implementation of the class:
class Qa::ErrorType < Qa::Base
set_table_name "error_types"
# Associations
has_many :transaction_errors, :class_name => 'Qa::TransactionError'
has_many :evaluations, :class_name => 'Qa::Evaluation', :through => :transaction_errors
# Validations
validates_presence_of :content
validates_uniqueness_of :content
end
All validations will work as they are meant to after this change. I think renaming the class Qa::Error as Qa::TransactionError is optional. I just did that so my naming convention is consistent throughout the application.
精彩评论