Module: Yogo::DataMapper::RepositoryManager::Resource

Defined in:
lib/yogo/datamapper/repository_manager/resource.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object

Ensure that models that we might store in the Project#managed_repository are properly migrated/upgrade whenever the Project changes.

See Also:

  • Project#prepare_models


9
10
11
12
13
14
15
# File 'lib/yogo/datamapper/repository_manager/resource.rb', line 9

def self.included(base)
  base.class_eval do
    after :save, :prepare_models
    after :create, :create_storage
    before :destroy, :destroy_storage
  end
end

Instance Method Details

#adapterObject



52
53
54
55
56
57
58
59
# File 'lib/yogo/datamapper/repository_manager/resource.rb', line 52

def adapter
  begin
    ::DataMapper.repository(managed_repository_name).adapter
  rescue ::DataMapper::RepositoryNotSetupError
    ::DataMapper.setup(managed_repository_name, adapter_config)
    retry
  end
end

#adapter_configHash

Returns The adapter configuration for the Project managed_repository.

Returns:

  • (Hash)

    The adapter configuration for the Project managed_repository

See Also:

  • DataMapper.setup


43
44
45
46
47
48
49
50
# File 'lib/yogo/datamapper/repository_manager/resource.rb', line 43

def adapter_config
  # Read the configuration from the existing database.yml file
  config = Rails.configuration.database_configuration
  adapter_conf = config['yogo-db'].dup
  adapter_conf['database'] = "#{adapter_conf['path']}#{managed_repository_database_name}"
  adapter_conf.delete("path")
  return adapter_conf
end

#build_managed(model_klass, attributes = {}) ⇒ Object

TODO:

Refactor into module in yogo-project

Builds a “new”, unsaved datamapper resource, that is explicitly bound to the Project#managed_repository. If you want to create a new resource that will be saved inside the repository of a Project, you should always use this method.

Boring Details:

Initially "new" model resources do not bind themselves to any repository.
At some point a "new" resource will persist itself and bind itself exclusively
to the repository that it "persisted into". This step is fiddly to catch, and
happens deep inside the DataMapper code. It is MUCH easier to explictly bind
the "new" resource to a particular repository immediately after calling #new.
This requires using reflection to modify the internal state of the resource object,
so it is best sealed inside a single method, rather than scattered throughout
the codebase.

Examples:

Create a new site that is stored in myProject.managed_repository

managedSite = myProject.build_managed(Voeis::Site, :name => ...)

Doing any of these will NOT work consistently (if at all)

managedSite1 = Voeis::Site.new(:name => ...)
managedSite1.save # WILL NOT save in myProject.managed_repository

managedSite2 = myProject.managed_repository{Voeis::Site.new(:name => ...)}
managedSite2.save # WILL NOT save in myProject.managed_repository


112
113
114
115
116
117
118
119
120
# File 'lib/yogo/datamapper/repository_manager/resource.rb', line 112

def build_managed(model_klass, attributes={})
  unless self.class.managed_models.include? model_klass
    self.class.manage(model_klass)
    prepare_models
  end
  res = model_klass.new(attributes)
  res.instance_variable_set(:@_repository, managed_repository)
  res
end

#create_storageObject



17
18
19
20
# File 'lib/yogo/datamapper/repository_manager/resource.rb', line 17

def create_storage
  ::DataMapper.repository.adapter.create_db(managed_repository_database_name)
  puts "Making new storage"
end

#destroy_storageObject



22
23
24
# File 'lib/yogo/datamapper/repository_manager/resource.rb', line 22

def destroy_storage
  puts "Nuking storage"
end

#managed_repository(&block) ⇒ Object



61
62
63
64
65
66
67
68
# File 'lib/yogo/datamapper/repository_manager/resource.rb', line 61

def managed_repository(&block)
  adapter # ensure the adapter get's setup or exists
  if block_given?
    ::DataMapper.repository(managed_repository_name, &block)
  else
    ::DataMapper.repository(managed_repository_name)
  end
end

#managed_repository_database_nameObject



35
36
37
# File 'lib/yogo/datamapper/repository_manager/resource.rb', line 35

def managed_repository_database_name
  "voeis_project_#{managed_repository_name}"
end

#managed_repository_nameSymbol

Override required from Yogo::DataMapper::Repository#managed_repository_name

Returns:

  • (Symbol)

    the name for the DataMapper::Repository that the Project manages



31
32
33
# File 'lib/yogo/datamapper/repository_manager/resource.rb', line 31

def managed_repository_name
  ActiveSupport::Inflector.tableize(id.to_s).to_sym
end

#prepare_modelsObject

TODO:

Refactor this method into a module in yogo-project

Ensure that models that models managed by the Project are properly migrated/upgraded inside the Project managed repository.



75
76
77
78
79
80
81
82
83
# File 'lib/yogo/datamapper/repository_manager/resource.rb', line 75

def prepare_models
  adapter # ensure the adapter exists or is setup
  managed_repository.scope {
    self.class.finalize_managed_models!
    self.class.managed_models.each do |klass|
      klass.auto_upgrade!
    end
  }
end