yogo-project 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|