2014-09-20 47 views
0

您可以告诉我Data Mapper的自动升级功能是如何工作的吗?DataMapper的auto_upgrade如何工作?

例如:

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! 

在这里,请问该数据映射的自动升级明白,他们必须创建一个数据库

+0

它只是检查数据库中是否存在,如果不,创建它。我没有得到这个问题。 – 2014-09-20 07:09:23

+0

它是如何理解User类是数据库的? – 2014-09-22 10:15:07

回答

1

首先,User类是数据库,它是模型,其链接到数据库

当你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] 
+0

谢谢你 – 2014-09-23 13:28:49