Modularized Models and Associations in ActiveRecord
Have you ever encountered this error?
wrong constant name X::YAssociationExtension
I found this error when dealing with acts_as_versioned for one my models. I would have found it eventually with any association I would have setup in this case, so it is not acts_as_versioned's fault.
I have an application with various parts so I create some of my models like this:
1 2 |
./script/generate model module_name::model_name |
So the fix is pretty simple, instead of winding up with ModuleName::ModelAssociationExtension or whatever, you want your extention module name to be ModelAssociationExtension.
Here is the method where the code breaks for me:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
def create_extension_modules(association_id, block_extension, extensions) if block_extension extension_module_name = "#{self.to_s}#{association_id.to_s.camelize}AssociationExtension" silence_warnings do Object.const_set(extension_module_name, Module.new(&block_extension)) end Array(extensions).push(extension_module_name.constantize) else Array(extensions) end end |
Here is the fix, on line 3, you will note the demodulize addition:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
def create_extension_modules(association_id, block_extension, extensions) if block_extension extension_module_name = "#{self.to_s.demodulize}#{association_id.to_s.camelize}AssociationExtension" silence_warnings do Object.const_set(extension_module_name, Module.new(&block_extension)) end Array(extensions).push(extension_module_name.constantize) else Array(extensions) end end |
I threw the corrected code into a library - RAILS_ROOT/lib/fix_active_record_create_extension_for_modules.rb. Make sure to open up the necessary modules to overwrite the method itself, I.e., like this:
1 2 3 4 5 6 7 8 |
module ActiveRecord module Associations module ClassMethods # the code above fits right here end end end |
Short and sweet, let me know if you have a better method for handling this.