вы можете попробовать что-то вроде этого:
module Mapper::Core
def self.included( base )
base.extend( ClassMethods )
end
module ClassMethods
# model class method to include matching module
# this will throw an error if matching class constant name does not exist
def has_mapping
@mapper_class = Kernel.const_get( "Mapper::#{self}Mapper" )
include @mapper_class
end
# an accessor to the matching class mapper may come in handy
def mapper_class
@mapper_class
end
end
end
, затем require
и include
модуля в ActiveRecord::Base
в инициализаторе (убедитесь, что для вашего модуля Mapper
требуются все файлы в папке 'mappers', или используйте config.autoload_paths
).
Если вы вообще не хотите использовать метод класса has_mapping
, вы можете попытаться переопределить self.inherited
обратный вызов ActiveRecord::Base
, но это может стать опасным:
def self.included( base )
base.extend( ClassMethods )
base.instance_eval <<-EOF
alias :old_inherited :inherited
def self.inherited( subclass )
subclass.has_mapping
old_inherited( subclass )
end
EOF
end
Я не пробовал ничего из этого, поэтому действуйте осторожно .
РЕДАКТИРОВАТЬ:
Я устал, когда писал это. Существует гораздо более простой способ автоматического включения соответствующего модуля:
module Mapper::Core
def self.included( base )
begin
mapper_class = Kernel.const_get( "Mapper::#{base.name}Mapper" )
base.instance_eval( "include #{mapper_class}" )
rescue
Logger.info "No matching Mapper Class found for #{base.name}"
end
end
end
инициализировать это с:
ActiveRecord::base.instance_eval( 'include Mapper::Core' )
весь наследующий класс теперь будет include Mapper::Core
, что приведет к включению соответствующего класса.