2014-09-20 39 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