您能否告诉我Data Mapper的自动升级功能如何运作?
例如:
include 'data_mapper'
DataMapper.setup :default, "sqlite://#{Dir.pwd}/base.db"
class User
include DataMapper::Resource
property :id, Serial
property :name, String
end
DataMapper.auto_upgrade!
此处,Data Mapper的自动升级如何理解他们必须创建数据库
答案 0 :(得分:1)
首先,User类不数据库,它是模型,它链接到表中的< EM>数据库
当您include DataMapper::Resource
时,它会自动调用extend DataMapper::Model
:
# https://github.com/datamapper/dm-core/blob/master/lib/dm-core/resource.rb#L55-L58
module DataMapper
module Resource
# ...
def self.included(model)
model.extend Model
super
end
# ...
end
end
此扩展调用被DataMapper::Model
中的另一个钩子拦截,该钩子跟踪模块的后代:
# https://github.com/datamapper/dm-core/blob/master/lib/dm-core/model.rb#L209-L223
module DataMapper
module Model
# ...
def self.descendants
@descendants ||= DescendantSet.new
end
# ...
def self.extended(descendant)
descendants << descendant
# ...
super
end
# ...
end
end
稍后,DataMapper可以通过DataMapper::Model.descendants
找到所有模型:
# https://github.com/datamapper/dm-migrations/blob/8bfcec08286a12ceee1bc3e5a01da3b5b7d4a74d/lib/dm-migrations/auto_migration.rb#L43-L50
module DataMapper
module Migrations
module SingletonMethods
# ...
def auto_upgrade!(repository_name = nil)
repository_execute(:auto_upgrade!, repository_name)
end
# ...
def repository_execute(method, repository_name)
models = DataMapper::Model.descendants
models = models.select { |m| m.default_repository_name == repository_name } if repository_name
models.each do |model|
model.send(method, model.default_repository_name)
end
end
# ...
end
end
end
这是一个最小的例子:
module Model
def self.descendants
@descendants ||= []
end
def self.extended(base)
descendants << base
super
end
end
module Resource
def self.included(base)
base.extend(Model)
end
end
class Car
include Resource
end
class Bike
include Resource
end
class Train
include Resource
end
Model.descendants
#=> [Car, Bike, Train]