你可以嘗試這樣的事:
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
模塊需要在您的「映射器」文件夾,或使用的所有文件config.autoload_paths
)。
如果你不希望在所有使用has_mapping
類方法,你可以嘗試重寫的ActiveRecord::Base
self.inherited
回調,但它可能會變得危險:
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
我沒有這條老命,所以謹慎行事。
編輯:
我累了,當我寫這一點。還有一個更簡單autoinclude匹配模塊方式:
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
,這將引發包括匹配類的。
感謝您抽出寶貴時間回答 - 我認爲這不值得冒險。 – Russell
是的。也這麼覺得。在重寫時忘記了調用':old_inherited',修復它。增加了另一種自動包含的方式。 –