yogo-project 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +27 -0
- data/Gemfile +34 -0
- data/Gemfile.lock +198 -0
- data/LICENSE +20 -0
- data/README.rdoc +17 -0
- data/Rakefile +56 -0
- data/VERSION +1 -0
- data/features/step_definitions/yogo_project_steps.rb +0 -0
- data/features/support/env.rb +1 -0
- data/features/yogo_project.feature +9 -0
- data/lib/datamapper/adapters/postgres.rb +9 -0
- data/lib/datamapper/adapters/sqlite.rb +9 -0
- data/lib/yogo-project.rb +2 -0
- data/lib/yogo/collection.rb +12 -0
- data/lib/yogo/collection/asset.rb +12 -0
- data/lib/yogo/collection/asset/model.rb +11 -0
- data/lib/yogo/collection/asset/model_configuration.rb +21 -0
- data/lib/yogo/collection/asset/model_properties.rb +47 -0
- data/lib/yogo/collection/base.rb +69 -0
- data/lib/yogo/collection/base/collection_repository.rb +21 -0
- data/lib/yogo/collection/base/model.rb +20 -0
- data/lib/yogo/collection/base/model_collection_context.rb +25 -0
- data/lib/yogo/collection/base/model_configuration.rb +34 -0
- data/lib/yogo/collection/data.rb +61 -0
- data/lib/yogo/collection/data/model.rb +72 -0
- data/lib/yogo/collection/data/model_configuration.rb +42 -0
- data/lib/yogo/collection/data/model_properties.rb +15 -0
- data/lib/yogo/collection/field_view.rb +26 -0
- data/lib/yogo/collection/form.rb +22 -0
- data/lib/yogo/collection/property.rb +127 -0
- data/lib/yogo/collection/static.rb +13 -0
- data/lib/yogo/collection/static/model_configuration.rb +31 -0
- data/lib/yogo/configuration.rb +9 -0
- data/lib/yogo/datamapper/model/common/properties.rb +16 -0
- data/lib/yogo/datamapper/model/configuration.rb +31 -0
- data/lib/yogo/datamapper/model/operations/add.rb +34 -0
- data/lib/yogo/datamapper/model/operations/clear.rb +29 -0
- data/lib/yogo/datamapper/model/stored/configuration.rb +25 -0
- data/lib/yogo/datamapper/repository_manager.rb +30 -0
- data/lib/yogo/datamapper/repository_manager/model.rb +40 -0
- data/lib/yogo/datamapper/repository_manager/resource.rb +124 -0
- data/lib/yogo/example/dynamic/project_full.rb +48 -0
- data/lib/yogo/example/dynamic/project_remix.rb +16 -0
- data/lib/yogo/example/voeis/managed/data_stream.rb +39 -0
- data/lib/yogo/example/voeis/managed/site.rb +51 -0
- data/lib/yogo/example/voeis/project.rb +57 -0
- data/lib/yogo/operation.rb +49 -0
- data/lib/yogo/project.rb +32 -0
- data/lib/yogo/property_ext.rb +7 -0
- data/spec/resource/.gitdir +0 -0
- data/spec/resource/text_file_asset.txt +1 -0
- data/spec/spec_helper.rb +49 -0
- data/spec/yogo/all_collection_data_models_spec.rb +34 -0
- data/spec/yogo/all_collection_managers_spec.rb +18 -0
- data/spec/yogo/all_collections_spec.rb +54 -0
- data/spec/yogo/all_data_collections_spec.rb +51 -0
- data/spec/yogo/asset_collection_spec.rb +28 -0
- data/spec/yogo/data_collection_spec.rb +16 -0
- data/yogo-project.gemspec +128 -0
- metadata +222 -0
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'dm-core'
|
2
|
+
require 'dm-types/uuid'
|
3
|
+
require 'dm-types/yaml'
|
4
|
+
|
5
|
+
require 'yogo/collection/property'
|
6
|
+
require 'yogo/collection/field_view'
|
7
|
+
|
8
|
+
module Yogo
|
9
|
+
module Collection
|
10
|
+
class Form
|
11
|
+
include ::DataMapper::Resource
|
12
|
+
|
13
|
+
property :id, UUID, :key => true, :default => lambda { |p,r| Yogo::Configuration.random_uuid }
|
14
|
+
property :name, String, :required => true
|
15
|
+
|
16
|
+
belongs_to :collection
|
17
|
+
has n, :field_views
|
18
|
+
has n, :fields, :through => :field_views
|
19
|
+
has n, :available_fields, :through => :collection, :model => 'Yogo::Collection::Property'
|
20
|
+
end # FieldView
|
21
|
+
end # Collection
|
22
|
+
end # Yogo
|
@@ -0,0 +1,127 @@
|
|
1
|
+
require 'dm-types/uuid'
|
2
|
+
require 'dm-types/yaml'
|
3
|
+
|
4
|
+
require 'yogo/configuration'
|
5
|
+
|
6
|
+
module Yogo
|
7
|
+
module Collection
|
8
|
+
class Property
|
9
|
+
include ::DataMapper::Resource
|
10
|
+
|
11
|
+
property :id, UUID, :key => true, :default => lambda { |p,r| Configuration.random_uuid }
|
12
|
+
property :name, String, :required => true
|
13
|
+
property :options, Yaml, :default => {}.to_yaml
|
14
|
+
property :type, Discriminator
|
15
|
+
|
16
|
+
property :data_collection_id, UUID
|
17
|
+
belongs_to :data_collection, :model => 'Yogo::Collection::Data'
|
18
|
+
|
19
|
+
# validates_uniqueness_of :name, :scope => :data_collection_id
|
20
|
+
|
21
|
+
def field_name
|
22
|
+
self.to_s
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_s
|
26
|
+
'field_' + self.id.to_s.gsub('-','_')
|
27
|
+
end
|
28
|
+
|
29
|
+
def as_json(opts=nil)
|
30
|
+
{
|
31
|
+
:id => self.id.to_s,
|
32
|
+
:type => self.type.to_s,
|
33
|
+
:field_name => self.to_s,
|
34
|
+
:name => self.name,
|
35
|
+
:options => self.options,
|
36
|
+
:data_collection => self.data_collection_id.to_s
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
def update_attributes(hash)
|
41
|
+
attrs = {}
|
42
|
+
attrs[:name] = hash[:name] || hash['name'] || self.name
|
43
|
+
attrs[:type] = hash[:type] || hash['type'] || self.type || self.class.name
|
44
|
+
attrs[:options] = hash[:options] || hash['options'] || self.options
|
45
|
+
self.attributes = attrs
|
46
|
+
end
|
47
|
+
|
48
|
+
def model_method
|
49
|
+
:property
|
50
|
+
end
|
51
|
+
|
52
|
+
def add_to_model(model)
|
53
|
+
prop_name = self.to_s.intern
|
54
|
+
prop_type = self.class
|
55
|
+
prop_options = self.options || {}
|
56
|
+
|
57
|
+
model.send(model_method, prop_name, prop_type, prop_options)
|
58
|
+
end
|
59
|
+
|
60
|
+
COMMON_PROPERTIES = [:String, :Text, :Integer, :Float, :Boolean, :Date, :Time, :DateTime]
|
61
|
+
COMMON_PROPERTIES.each do |type|
|
62
|
+
class_eval %{
|
63
|
+
class #{type} < Property; end
|
64
|
+
}
|
65
|
+
end
|
66
|
+
end # Property
|
67
|
+
|
68
|
+
|
69
|
+
class Relationship < Property
|
70
|
+
property :target_collection_id, UUID
|
71
|
+
belongs_to :target_collection, :model => 'Yogo::Collection::Data'
|
72
|
+
|
73
|
+
def as_json(options=nil)
|
74
|
+
hash = super
|
75
|
+
hash[:target_collection_id] = self.target_collection_id.to_s
|
76
|
+
hash
|
77
|
+
end
|
78
|
+
|
79
|
+
def target_model
|
80
|
+
target_collection.data_model
|
81
|
+
end
|
82
|
+
|
83
|
+
def model_method
|
84
|
+
:has
|
85
|
+
end
|
86
|
+
|
87
|
+
def check_target
|
88
|
+
raise ":target not set" unless self.target && !self.target.empty?
|
89
|
+
end
|
90
|
+
|
91
|
+
def add_to_model(model, n, options={})
|
92
|
+
check_target
|
93
|
+
model.send(model_method, n, ActiveSupport::Inflector.tableize(self.target).intern, options.merge(self.options))
|
94
|
+
end
|
95
|
+
|
96
|
+
class ManyToMany < self
|
97
|
+
def add_to_model(model)
|
98
|
+
super(model, Infinity, :through => ::DataMapper::Resource)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
class OneToMany < self
|
103
|
+
def add_to_model(model)
|
104
|
+
super(model)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
class OneToOne < self
|
109
|
+
def add_to_model(model)
|
110
|
+
super(model, 1)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
class ManyToOne < self
|
115
|
+
def model_method
|
116
|
+
:belongs_to
|
117
|
+
end
|
118
|
+
|
119
|
+
def add_to_model(model)
|
120
|
+
check_target
|
121
|
+
model.send(model_method, ActiveSupport::Inflector.underscore(self.target).intern, options.merge(self.options))
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
126
|
+
end # Collection
|
127
|
+
end # Yogo
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'yogo/collection/data'
|
2
|
+
|
3
|
+
module Yogo
|
4
|
+
module Collection
|
5
|
+
class Static < Data
|
6
|
+
require 'yogo/collection/static/model_configuration'
|
7
|
+
include Static::ModelConfiguration
|
8
|
+
|
9
|
+
property :static_model, String
|
10
|
+
|
11
|
+
end # Asset
|
12
|
+
end # Collection
|
13
|
+
end # Yogo
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Yogo
|
2
|
+
module Collection
|
3
|
+
class Static
|
4
|
+
module ModelConfiguration
|
5
|
+
def model_generate
|
6
|
+
model_name = self.static_model
|
7
|
+
ActiveSupport::Inflector.constantize(model_name)
|
8
|
+
end
|
9
|
+
|
10
|
+
def before_model_generate
|
11
|
+
end
|
12
|
+
|
13
|
+
def after_model_generate(model)
|
14
|
+
model
|
15
|
+
end
|
16
|
+
|
17
|
+
def model_update(model)
|
18
|
+
model.extend(Base::ModelCollectionContext) unless model.respond_to?(:current_collection)
|
19
|
+
end
|
20
|
+
|
21
|
+
def before_model_update(model)
|
22
|
+
model
|
23
|
+
end
|
24
|
+
|
25
|
+
def after_model_update(model)
|
26
|
+
model
|
27
|
+
end
|
28
|
+
end # ModelConfiguration
|
29
|
+
end # Static
|
30
|
+
end # Collection
|
31
|
+
end # Yogo
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'configatron'
|
2
|
+
|
3
|
+
module Yogo
|
4
|
+
Configuration = Configatron::Store.new
|
5
|
+
Configuration.random_uuid = Configatron::Dynamic.new { UUIDTools::UUID.timestamp_create }
|
6
|
+
Configuration.collection.set_default(:data_repository_name, :collection_data)
|
7
|
+
Configuration.collection.asset.set_default(:storage_dir, 'asset_collection')
|
8
|
+
end
|
9
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'yogo/operation'
|
2
|
+
require 'yogo/datamapper/model/operations/add'
|
3
|
+
require 'dm-types/uuid'
|
4
|
+
|
5
|
+
module Yogo
|
6
|
+
module DataMapper
|
7
|
+
module Model
|
8
|
+
module Common
|
9
|
+
module Properties
|
10
|
+
UUIDKey = Operations::Add::Property.partial(X, :id, ::DataMapper::Property::UUID, {:key => true, :default => lambda{|*args| UUIDTools::UUID.timestamp_create}})
|
11
|
+
|
12
|
+
end # Properties
|
13
|
+
end # Common
|
14
|
+
end # Model
|
15
|
+
end # DataMapper
|
16
|
+
end # Yogo
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'yogo/datamapper/model/operations/clear'
|
2
|
+
require 'yogo/datamapper/model/operations/add'
|
3
|
+
|
4
|
+
module Yogo
|
5
|
+
module DataMapper
|
6
|
+
module Model
|
7
|
+
module Configuration
|
8
|
+
|
9
|
+
def operation_definitions
|
10
|
+
@_operation_definitions ||= []
|
11
|
+
end
|
12
|
+
|
13
|
+
def operation(op_name, *args)
|
14
|
+
op_def = [op_name.to_s, args].flatten
|
15
|
+
operation_definitions << op_def unless operation_definitions.include?(op_def)
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_proc
|
19
|
+
ops = operation_definitions.map{|op_def| Operations[op_def.first] }
|
20
|
+
partial_ops = []
|
21
|
+
ops.each_with_index do |op, i|
|
22
|
+
next unless op
|
23
|
+
partial_ops[i] = op.partial(X, *operation_definitions[i][1..-1])
|
24
|
+
end
|
25
|
+
partial_ops.compact!
|
26
|
+
partial_ops.reduce{|composed, partial_op| composed * partial_op}
|
27
|
+
end
|
28
|
+
end # Configuration
|
29
|
+
end # Model
|
30
|
+
end # DataMapper
|
31
|
+
end # Yogo
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'yogo/operation'
|
2
|
+
|
3
|
+
module Yogo
|
4
|
+
module DataMapper
|
5
|
+
module Model
|
6
|
+
module Operations
|
7
|
+
module Add
|
8
|
+
Property = Operation.on(::DataMapper::Model) do |model, name, type, options|
|
9
|
+
type ||= String
|
10
|
+
options ||= {}
|
11
|
+
model.property(name, type, options)
|
12
|
+
model
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
Relationship = Operation.on(::DataMapper::Model) do |model, method, *args|
|
17
|
+
model.send(method, *args)
|
18
|
+
model
|
19
|
+
end
|
20
|
+
|
21
|
+
HasRelationship = Relationship.partial(X, :has, X, X, X)
|
22
|
+
|
23
|
+
HasN = HasRelationship.partial(X, Infinity, X, X)
|
24
|
+
|
25
|
+
HasOne = HasRelationship.partial(X, 1, X, X)
|
26
|
+
|
27
|
+
BelongsTo = Relationship.partial(X, :belongs_to, X, X)
|
28
|
+
|
29
|
+
|
30
|
+
end # Add
|
31
|
+
end # Operations
|
32
|
+
end # Model
|
33
|
+
end # DataMapper
|
34
|
+
end # Yogo
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'yogo/operation'
|
2
|
+
|
3
|
+
module Yogo
|
4
|
+
module DataMapper
|
5
|
+
module Model
|
6
|
+
module Operations
|
7
|
+
module Clear
|
8
|
+
Properties = Operation.on(::DataMapper::Model) do |model|
|
9
|
+
model.properties.clear
|
10
|
+
model.properties.instance_variable_get(:@properties).clear #clear out the name index
|
11
|
+
model
|
12
|
+
end
|
13
|
+
|
14
|
+
Relationships = Operation.on(::DataMapper::Model) do |model|
|
15
|
+
model.relationships.clear
|
16
|
+
model
|
17
|
+
end
|
18
|
+
|
19
|
+
Validators = Operation.on(::DataMapper::Model) do |model|
|
20
|
+
model.validators.clear!
|
21
|
+
model
|
22
|
+
end
|
23
|
+
|
24
|
+
All = Properties * Relationships * Validators
|
25
|
+
end # Clear
|
26
|
+
end # Operations
|
27
|
+
end # Model
|
28
|
+
end # DataMapper
|
29
|
+
end # Yogo
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'yogo/configuration'
|
2
|
+
require 'yogo/datamapper/model/configuration'
|
3
|
+
require 'yogo/datamapper/model/common/properties'
|
4
|
+
|
5
|
+
require 'dm-types/uuid'
|
6
|
+
require 'dm-types/yaml'
|
7
|
+
|
8
|
+
module Yogo
|
9
|
+
module DataMapper
|
10
|
+
module Model
|
11
|
+
module Stored
|
12
|
+
module Configuration
|
13
|
+
include ::DataMapper::Resource
|
14
|
+
include Dynamic::Configuration
|
15
|
+
|
16
|
+
is :remixable
|
17
|
+
|
18
|
+
Common::Properties::UUIDKey[self]
|
19
|
+
|
20
|
+
property :operation_definitions, Yaml, :default => lambda {|*args| []}
|
21
|
+
end # Configuration
|
22
|
+
end # Stored
|
23
|
+
end # Model
|
24
|
+
end # DataMapper
|
25
|
+
end # Yogo
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'yogo/datamapper/repository_manager/model'
|
2
|
+
require 'yogo/datamapper/repository_manager/resource'
|
3
|
+
|
4
|
+
module Yogo
|
5
|
+
module DataMapper
|
6
|
+
module RepositoryManager
|
7
|
+
def self.included(base)
|
8
|
+
base.class_eval do
|
9
|
+
extend(RepositoryManager::Model)
|
10
|
+
include(RepositoryManager::Resource)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end # RepositoryManager
|
14
|
+
end # DataMapper
|
15
|
+
end # Yogo
|
16
|
+
|
17
|
+
module DataMapper
|
18
|
+
module Is
|
19
|
+
module RepositoryManager
|
20
|
+
def is_repository_manager
|
21
|
+
include(Yogo::DataMapper::RepositoryManager)
|
22
|
+
end
|
23
|
+
end # RepositoryManager
|
24
|
+
end # Is
|
25
|
+
|
26
|
+
if const_defined?("Model")
|
27
|
+
Model.append_extensions(Is::RepositoryManager)
|
28
|
+
end
|
29
|
+
end # module DataMapper
|
30
|
+
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Yogo
|
2
|
+
module DataMapper
|
3
|
+
module RepositoryManager
|
4
|
+
module Model
|
5
|
+
# Class method for informing Project instances about what kinds of models
|
6
|
+
# might be stored inside thier Project#managed_repository.
|
7
|
+
#
|
8
|
+
# @param [DataMapper::Model] model class that might be stored in Project managed_repositories
|
9
|
+
# @return [Array<DataMapper::Model>] list of currently managed models
|
10
|
+
def manage(*args)
|
11
|
+
@managed_models ||= []
|
12
|
+
models = args
|
13
|
+
|
14
|
+
@managed_models += models
|
15
|
+
@managed_models.uniq!
|
16
|
+
|
17
|
+
@managed_models
|
18
|
+
end
|
19
|
+
|
20
|
+
# Models that are currently managed by Project instances.
|
21
|
+
# @return [Array<DataMapper::Model>] list of currently managed models
|
22
|
+
def managed_models
|
23
|
+
@managed_models
|
24
|
+
end
|
25
|
+
|
26
|
+
# Ensure that Relation models are also managed
|
27
|
+
def finalize_managed_models!
|
28
|
+
models = []
|
29
|
+
@managed_models.each do |m|
|
30
|
+
models += m.relationships.values.map{|r| r.child_model }
|
31
|
+
models += m.relationships.values.map{|r| r.parent_model }
|
32
|
+
end
|
33
|
+
@managed_models += models
|
34
|
+
@managed_models.uniq!
|
35
|
+
@managed_models
|
36
|
+
end
|
37
|
+
end # Model
|
38
|
+
end # RepositoryManager
|
39
|
+
end # DataMapper
|
40
|
+
end # Yogo
|
@@ -0,0 +1,124 @@
|
|
1
|
+
module Yogo
|
2
|
+
module DataMapper
|
3
|
+
module RepositoryManager
|
4
|
+
module Resource
|
5
|
+
# Ensure that models that we might store in the Project#managed_repository
|
6
|
+
# are properly migrated/upgrade whenever the Project changes.
|
7
|
+
# @author Ryan Heimbuch
|
8
|
+
# @see Project#prepare_models
|
9
|
+
def self.included(base)
|
10
|
+
base.class_eval do
|
11
|
+
after :save, :prepare_models
|
12
|
+
after :create, :create_storage
|
13
|
+
before :destroy, :destroy_storage
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def create_storage
|
18
|
+
::DataMapper.repository.adapter.create_db(managed_repository_database_name)
|
19
|
+
puts "Making new storage"
|
20
|
+
end
|
21
|
+
|
22
|
+
def destroy_storage
|
23
|
+
puts "Nuking storage"
|
24
|
+
end
|
25
|
+
|
26
|
+
# @author Ryan Heimbuch
|
27
|
+
#
|
28
|
+
# Override required from Yogo::DataMapper::Repository#managed_repository_name
|
29
|
+
#
|
30
|
+
# @return [Symbol] the name for the DataMapper::Repository that the Project manages
|
31
|
+
def managed_repository_name
|
32
|
+
ActiveSupport::Inflector.tableize(id.to_s).to_sym
|
33
|
+
end
|
34
|
+
|
35
|
+
def managed_repository_database_name
|
36
|
+
"voeis_project_#{managed_repository_name}"
|
37
|
+
end
|
38
|
+
|
39
|
+
# @author Ryan Heimbuch
|
40
|
+
#
|
41
|
+
# @return [Hash] The adapter configuration for the Project managed_repository
|
42
|
+
# @see DataMapper.setup
|
43
|
+
def adapter_config
|
44
|
+
# Read the configuration from the existing database.yml file
|
45
|
+
config = Rails.configuration.database_configuration
|
46
|
+
adapter_conf = config['yogo-db'].dup
|
47
|
+
adapter_conf['database'] = "#{adapter_conf['path']}#{managed_repository_database_name}"
|
48
|
+
adapter_conf.delete("path")
|
49
|
+
return adapter_conf
|
50
|
+
end
|
51
|
+
|
52
|
+
def adapter
|
53
|
+
begin
|
54
|
+
::DataMapper.repository(managed_repository_name).adapter
|
55
|
+
rescue ::DataMapper::RepositoryNotSetupError
|
56
|
+
::DataMapper.setup(managed_repository_name, adapter_config)
|
57
|
+
retry
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def managed_repository(&block)
|
62
|
+
adapter # ensure the adapter get's setup or exists
|
63
|
+
if block_given?
|
64
|
+
::DataMapper.repository(managed_repository_name, &block)
|
65
|
+
else
|
66
|
+
::DataMapper.repository(managed_repository_name)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Ensure that models that models managed by the Project
|
71
|
+
# are properly migrated/upgraded inside the Project managed repository.
|
72
|
+
#
|
73
|
+
# @author Ryan Heimbuch
|
74
|
+
# @todo Refactor this method into a module in yogo-project
|
75
|
+
def prepare_models
|
76
|
+
adapter # ensure the adapter exists or is setup
|
77
|
+
managed_repository.scope {
|
78
|
+
self.class.finalize_managed_models!
|
79
|
+
self.class.managed_models.each do |klass|
|
80
|
+
klass.auto_upgrade!
|
81
|
+
end
|
82
|
+
}
|
83
|
+
end
|
84
|
+
|
85
|
+
# Builds a "new", unsaved datamapper resource, that is explicitly
|
86
|
+
# bound to the Project#managed_repository.
|
87
|
+
# If you want to create a new resource that will be saved inside the
|
88
|
+
# repository of a Project, you should always use this method.
|
89
|
+
#
|
90
|
+
# @example Create a new site that is stored in myProject.managed_repository
|
91
|
+
# managedSite = myProject.build_managed(Voeis::Site, :name => ...)
|
92
|
+
#
|
93
|
+
# @example Doing any of these will NOT work consistently (if at all)
|
94
|
+
# managedSite1 = Voeis::Site.new(:name => ...)
|
95
|
+
# managedSite1.save # WILL NOT save in myProject.managed_repository
|
96
|
+
#
|
97
|
+
# managedSite2 = myProject.managed_repository{Voeis::Site.new(:name => ...)}
|
98
|
+
# managedSite2.save # WILL NOT save in myProject.managed_repository
|
99
|
+
#
|
100
|
+
# Boring Details:
|
101
|
+
# Initially "new" model resources do not bind themselves to any repository.
|
102
|
+
# At some point a "new" resource will persist itself and bind itself exclusively
|
103
|
+
# to the repository that it "persisted into". This step is fiddly to catch, and
|
104
|
+
# happens deep inside the DataMapper code. It is MUCH easier to explictly bind
|
105
|
+
# the "new" resource to a particular repository immediately after calling #new.
|
106
|
+
# This requires using reflection to modify the internal state of the resource object,
|
107
|
+
# so it is best sealed inside a single method, rather than scattered throughout
|
108
|
+
# the codebase.
|
109
|
+
#
|
110
|
+
# @todo Refactor into module in yogo-project
|
111
|
+
# @author Ryan Heimbuch
|
112
|
+
def build_managed(model_klass, attributes={})
|
113
|
+
unless self.class.managed_models.include? model_klass
|
114
|
+
self.class.manage(model_klass)
|
115
|
+
prepare_models
|
116
|
+
end
|
117
|
+
res = model_klass.new(attributes)
|
118
|
+
res.instance_variable_set(:@_repository, managed_repository)
|
119
|
+
res
|
120
|
+
end
|
121
|
+
end # RepositoryModels
|
122
|
+
end # RepositoryManager
|
123
|
+
end # DataMapper
|
124
|
+
end # Yogo
|