2014-09-20 6 views
0

Pouvez-vous s'il vous plaît me dire comment fonctionne la mise à jour automatique de Data Mapper?Comment fonctionne la mise à jour automatique de DataMapper?

Par exemple:

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! 

Ici, comment est-ce que la mise à jour automatique de données Mapper comprendre qu'ils doivent créer une base de données

+0

Il vérifie simplement si la base de données existe et sinon, crée. Je ne comprends pas la question. –

+0

Comment comprend-il que la classe User est une base de données? –

Répondre

1

Tout d'abord, la classe utilisateur est pas une base de données, c'est un modèle, qui est lié à une table dans une base de données .

Lorsque vous include DataMapper::Resource, il appellera automatiquement 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 

cet appel d'étendre est intercepté par un autre crochet dans DataMapper::Model, qui garde la trace des descendants du module:

# 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 

plus tard, DataMapper peut trouver tous les modèles via 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 

Voici un exemple minimal:

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

Merci pour cela –