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

Author:

  • Ryan Heimbuch



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



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

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

Author:

  • Ryan Heimbuch



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

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

Author:

  • Ryan Heimbuch



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

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
# File 'lib/yogo/datamapper/repository_manager/resource.rb', line 17

def create_storage
  ::DataMapper.repository.adapter.create_db(managed_repository_database_name)
end

#destroy_storageObject



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

def destroy_storage
  # TODO: Implement me.
end

#managed_repository(&block) ⇒ Object



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

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



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

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

Author:

  • Ryan Heimbuch



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

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.

Author:

  • Ryan Heimbuch



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

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