locomotive_plugins 1.0.0.beta3 → 1.0.0.beta4
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/lib/locomotive/plugin.rb +6 -3
- data/lib/locomotive/plugin/db_model_container.rb +8 -0
- data/lib/locomotive/plugin/db_models.rb +40 -15
- data/lib/version.rb +1 -1
- data/spec/lib/locomotive/plugin/db_models_spec.rb +152 -2
- data/spec/lib/locomotive/plugin_spec.rb +7 -0
- data/spec/support/plugins/plugin_with_db_model_relationships.rb +22 -0
- metadata +3 -2
data/lib/locomotive/plugin.rb
CHANGED
@@ -117,11 +117,14 @@ module Locomotive
|
|
117
117
|
|
118
118
|
# Initialize by supplying the current config parameters. Note that this
|
119
119
|
# method should not be overridden for custom initialization of plugin
|
120
|
-
# objects. Instead, override the initialize_plugin method
|
120
|
+
# objects. Instead, override the initialize_plugin method. If given a
|
121
|
+
# block, the block will be called with `self` as an argument before the
|
122
|
+
# `initialize_plugin` method is called. This is used by LocomotiveCMS to
|
123
|
+
# perform some custom initialization before the plugin's initialization is
|
124
|
+
# called.
|
121
125
|
def initialize(config)
|
122
126
|
self.config = config
|
123
|
-
self
|
124
|
-
self.save_db_model_container
|
127
|
+
yield self if block_given?
|
125
128
|
self.initialize_plugin
|
126
129
|
end
|
127
130
|
|
@@ -5,6 +5,14 @@ module Locomotive
|
|
5
5
|
# container has the actual relationships to the database objects
|
6
6
|
class DBModelContainer
|
7
7
|
include Mongoid::Document
|
8
|
+
|
9
|
+
field :container_name
|
10
|
+
|
11
|
+
def self.for_name(container_name)
|
12
|
+
where(container_name: container_name).first || \
|
13
|
+
new(container_name: container_name)
|
14
|
+
end
|
15
|
+
|
8
16
|
end
|
9
17
|
end
|
10
18
|
end
|
@@ -33,18 +33,21 @@ module Locomotive
|
|
33
33
|
protected
|
34
34
|
|
35
35
|
def create_has_many_relationship(name, klass)
|
36
|
-
self.db_model_container_class.
|
37
|
-
class_name: klass.to_s, inverse_of: :db_model_container
|
38
|
-
|
36
|
+
self.db_model_container_class.has_many(name,
|
37
|
+
class_name: klass.to_s, inverse_of: :db_model_container,
|
38
|
+
autosave: true, dependent: :destroy)
|
39
|
+
klass.belongs_to(:db_model_container,
|
39
40
|
class_name: db_model_container_class.to_s, inverse_of: name)
|
40
41
|
|
41
|
-
self.define_passthrough_methods_to_container(name, "#{name}="
|
42
|
+
self.define_passthrough_methods_to_container(name, "#{name}=",
|
43
|
+
"#{name}_ids", "#{name}_ids=")
|
42
44
|
end
|
43
45
|
|
44
46
|
def create_has_one_relationship(name, klass)
|
45
|
-
self.db_model_container_class.
|
46
|
-
class_name: klass.to_s, inverse_of: :db_model_container
|
47
|
-
|
47
|
+
self.db_model_container_class.has_one(name,
|
48
|
+
class_name: klass.to_s, inverse_of: :db_model_container,
|
49
|
+
autosave: true, dependent: :destroy)
|
50
|
+
klass.belongs_to(:db_model_container,
|
48
51
|
class_name: db_model_container_class.to_s, inverse_of: name)
|
49
52
|
|
50
53
|
self.define_passthrough_methods_to_container(name, "#{name}=",
|
@@ -52,13 +55,13 @@ module Locomotive
|
|
52
55
|
end
|
53
56
|
|
54
57
|
def define_passthrough_methods_to_container(*methods)
|
55
|
-
class_eval
|
56
|
-
|
58
|
+
class_eval do
|
59
|
+
methods.each do |meth|
|
57
60
|
define_method(meth) do |*args|
|
58
|
-
|
61
|
+
db_model_container.send(meth, *args)
|
59
62
|
end
|
60
63
|
end
|
61
|
-
|
64
|
+
end
|
62
65
|
end
|
63
66
|
|
64
67
|
end
|
@@ -70,14 +73,36 @@ module Locomotive
|
|
70
73
|
|
71
74
|
# Get the DB Model container
|
72
75
|
def db_model_container
|
73
|
-
@
|
76
|
+
@db_model_containers ||= {}
|
77
|
+
name = self.current_db_model_container_name
|
78
|
+
@db_model_containers[name] ||= load_db_model_container(name)
|
79
|
+
end
|
80
|
+
|
81
|
+
# Set the current DB Model container
|
82
|
+
def use_db_model_container(name)
|
83
|
+
@current_db_model_container_name = name
|
84
|
+
end
|
85
|
+
|
86
|
+
# Reset to the default DB Model container
|
87
|
+
def reset_current_db_model_container
|
88
|
+
self.use_db_model_container(nil)
|
89
|
+
end
|
90
|
+
|
91
|
+
# Set the current DB Model container for the duration of the block
|
92
|
+
def with_db_model_container(name, &block)
|
93
|
+
old_name = self.current_db_model_container_name
|
94
|
+
self.use_db_model_container(name)
|
95
|
+
block.call
|
96
|
+
self.use_db_model_container(old_name)
|
74
97
|
end
|
75
98
|
|
99
|
+
# The name of the current container being used
|
100
|
+
attr_reader :current_db_model_container_name
|
101
|
+
|
76
102
|
protected
|
77
103
|
|
78
|
-
def
|
79
|
-
|
80
|
-
|| self.class.db_model_container_class.new
|
104
|
+
def load_db_model_container(name)
|
105
|
+
self.class.db_model_container_class.for_name(name)
|
81
106
|
end
|
82
107
|
|
83
108
|
end
|
data/lib/version.rb
CHANGED
@@ -31,7 +31,7 @@ module Locomotive
|
|
31
31
|
@plugin_with_db_model.items.where(name: /Item/)[1].name.should == 'Second Item'
|
32
32
|
end
|
33
33
|
|
34
|
-
it 'should
|
34
|
+
it 'should reference DBModel items in a document for the plugin class' do
|
35
35
|
@plugin_with_db_model.visit_count.db_model_container.kind_of?(
|
36
36
|
PluginWithDBModel::DBModelContainer).should be_true
|
37
37
|
@plugin_with_db_model.items.first.db_model_container.kind_of?(
|
@@ -39,7 +39,10 @@ module Locomotive
|
|
39
39
|
|
40
40
|
@plugin_with_db_model.visit_count.relations[
|
41
41
|
'db_model_container'].relation.should \
|
42
|
-
== Mongoid::Relations::
|
42
|
+
== Mongoid::Relations::Referenced::In
|
43
|
+
@plugin_with_db_model.items.relations[
|
44
|
+
'db_model_container'].relation.should \
|
45
|
+
== Mongoid::Relations::Referenced::In
|
43
46
|
end
|
44
47
|
|
45
48
|
it 'should run all validations for DBModel items' do
|
@@ -51,6 +54,153 @@ module Locomotive
|
|
51
54
|
}
|
52
55
|
end
|
53
56
|
|
57
|
+
it 'should destroy the contained objects when the container is destroyed' do
|
58
|
+
vc = @plugin_with_db_model.visit_count
|
59
|
+
i0 = @plugin_with_db_model.items[0]
|
60
|
+
i1 = @plugin_with_db_model.items[1]
|
61
|
+
|
62
|
+
DBModel.all.for_ids(vc.id, i0.id, i1.id).count.should == 3
|
63
|
+
|
64
|
+
@plugin_with_db_model.db_model_container.destroy
|
65
|
+
|
66
|
+
DBModel.all.for_ids(vc.id, i0.id, i1.id).count.should == 0
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should allow relationships between DBModels' do
|
70
|
+
plugin = PluginWithDBModelRelationships.new({})
|
71
|
+
|
72
|
+
t1 = plugin.teachers.build(name: 'Mr. Adams')
|
73
|
+
t2 = plugin.teachers.build(name: 'Ms. Boudreau')
|
74
|
+
|
75
|
+
s1 = plugin.students.build(name: 'Alex', teacher: t1)
|
76
|
+
s2 = plugin.students.build(name: 'Billy', teacher: t1)
|
77
|
+
s3 = plugin.students.build(name: 'Caitlyn', teacher: t2)
|
78
|
+
|
79
|
+
plugin.save_db_model_container.should be_true
|
80
|
+
|
81
|
+
# Reload from database
|
82
|
+
plugin = PluginWithDBModelRelationships.new({})
|
83
|
+
|
84
|
+
# Check all the names and relationships to make sure they were
|
85
|
+
# persisted
|
86
|
+
teachers = plugin.teachers.to_a
|
87
|
+
students = plugin.students.to_a
|
88
|
+
|
89
|
+
teachers[0].name.should == 'Mr. Adams'
|
90
|
+
teachers[0].students.count.should == 2
|
91
|
+
teachers[0].students.should include(s1)
|
92
|
+
teachers[0].students.should include(s2)
|
93
|
+
|
94
|
+
teachers[1].name.should == 'Ms. Boudreau'
|
95
|
+
teachers[1].students.count.should == 1
|
96
|
+
teachers[1].students.should include(s3)
|
97
|
+
|
98
|
+
s1.name.should == 'Alex'
|
99
|
+
s1.teacher.should == t1
|
100
|
+
s2.name.should == 'Billy'
|
101
|
+
s2.teacher.should == t1
|
102
|
+
s3.name.should == 'Caitlyn'
|
103
|
+
s3.teacher.should == t2
|
104
|
+
end
|
105
|
+
|
106
|
+
context 'with multiple containers' do
|
107
|
+
|
108
|
+
it 'should save the data in the correct container' do
|
109
|
+
plugin = PluginWithDBModel.new({})
|
110
|
+
|
111
|
+
plugin.with_db_model_container('my_container') do
|
112
|
+
plugin.build_visit_count(count: 10)
|
113
|
+
end
|
114
|
+
|
115
|
+
plugin.use_db_model_container('my_other_container')
|
116
|
+
plugin.build_visit_count(count: 20)
|
117
|
+
plugin.save_db_model_container.should be_true
|
118
|
+
plugin.reset_current_db_model_container
|
119
|
+
|
120
|
+
plugin.use_db_model_container('my_container')
|
121
|
+
plugin.db_model_container.changed?.should be_true
|
122
|
+
plugin.save_db_model_container.should be_true
|
123
|
+
plugin.db_model_container.changed?.should be_false
|
124
|
+
|
125
|
+
# Reload from the database
|
126
|
+
@plugin_with_db_model = PluginWithDBModel.new({})
|
127
|
+
|
128
|
+
# Make sure everything is in the right container and make sure we can
|
129
|
+
# access the containers how we want
|
130
|
+
@plugin_with_db_model.with_db_model_container('my_other_container') do
|
131
|
+
@plugin_with_db_model.current_db_model_container_name.should ==
|
132
|
+
'my_other_container'
|
133
|
+
@plugin_with_db_model.visit_count.count.should == 20
|
134
|
+
end
|
135
|
+
|
136
|
+
@plugin_with_db_model.use_db_model_container('my_container')
|
137
|
+
@plugin_with_db_model.current_db_model_container_name.should ==
|
138
|
+
'my_container'
|
139
|
+
@plugin_with_db_model.visit_count.count.should == 10
|
140
|
+
|
141
|
+
@plugin_with_db_model.reset_current_db_model_container
|
142
|
+
@plugin_with_db_model.current_db_model_container_name.should be_nil
|
143
|
+
@plugin_with_db_model.visit_count.count.should == 5
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'should revert the current container name after using with_db_model_container' do
|
147
|
+
@plugin_with_db_model.use_db_model_container('fake_container')
|
148
|
+
@plugin_with_db_model.current_db_model_container_name.should ==
|
149
|
+
'fake_container'
|
150
|
+
|
151
|
+
@plugin_with_db_model.with_db_model_container('my_container') do
|
152
|
+
@plugin_with_db_model.current_db_model_container_name.should ==
|
153
|
+
'my_container'
|
154
|
+
end
|
155
|
+
|
156
|
+
@plugin_with_db_model.current_db_model_container_name.should ==
|
157
|
+
'fake_container'
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'should only load each container once' do
|
161
|
+
container_names = %w{my_container my_other_container}
|
162
|
+
|
163
|
+
# The default container has already been loaded
|
164
|
+
@plugin_with_db_model.expects(:load_db_model_container).with(nil).never
|
165
|
+
|
166
|
+
# The others should only be called once. Just return something
|
167
|
+
# non-nil
|
168
|
+
container_names.each do |name|
|
169
|
+
@plugin_with_db_model.expects(:load_db_model_container).with(
|
170
|
+
name).returns(1).once
|
171
|
+
end
|
172
|
+
|
173
|
+
3.times do
|
174
|
+
container_names.each do |name|
|
175
|
+
@plugin_with_db_model.with_db_model_container(name) do
|
176
|
+
# Access the container
|
177
|
+
@plugin_with_db_model.db_model_container
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
it 'should not share containers between plugin objects' do
|
184
|
+
p0 = PluginWithDBModel.new({})
|
185
|
+
p1 = PluginWithDBModelRelationships.new({})
|
186
|
+
|
187
|
+
# Default container
|
188
|
+
p0.save_db_model_container.should be_true
|
189
|
+
p1.save_db_model_container.should be_true
|
190
|
+
p0.db_model_container.should_not == p1.db_model_container
|
191
|
+
|
192
|
+
# Named container
|
193
|
+
p0.with_db_model_container('my_container') do
|
194
|
+
p1.with_db_model_container('my_container') do
|
195
|
+
p0.save_db_model_container.should be_true
|
196
|
+
p1.save_db_model_container.should be_true
|
197
|
+
p0.db_model_container.should_not == p1.db_model_container
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
end
|
203
|
+
|
54
204
|
end
|
55
205
|
end
|
56
206
|
end
|
@@ -14,6 +14,13 @@ module Locomotive
|
|
14
14
|
@plugin.custom_attribute.should == 'Value'
|
15
15
|
end
|
16
16
|
|
17
|
+
it 'should call the gven block before custom initialization methods' do
|
18
|
+
@plugin = MyPlugin.new(@config) do |obj|
|
19
|
+
obj.custom_attribute.should be_nil
|
20
|
+
end
|
21
|
+
@plugin.custom_attribute.should_not be_nil
|
22
|
+
end
|
23
|
+
|
17
24
|
it 'should store a list of before_filters' do
|
18
25
|
@plugin.before_filters.count.should == 2
|
19
26
|
@plugin.before_filters[0].should == :my_method1
|
@@ -0,0 +1,22 @@
|
|
1
|
+
|
2
|
+
module Locomotive
|
3
|
+
class PluginWithDBModelRelationships
|
4
|
+
include Locomotive::Plugin
|
5
|
+
|
6
|
+
class Teacher < Locomotive::Plugin::DBModel
|
7
|
+
field :name
|
8
|
+
has_many :students,
|
9
|
+
class_name: 'Locomotive::PluginWithDBModelRelationships::Student'
|
10
|
+
end
|
11
|
+
|
12
|
+
class Student < Locomotive::Plugin::DBModel
|
13
|
+
field :name
|
14
|
+
belongs_to :teacher,
|
15
|
+
class_name: 'Locomotive::PluginWithDBModelRelationships::Teacher'
|
16
|
+
end
|
17
|
+
|
18
|
+
has_many :teachers, Teacher
|
19
|
+
has_many :students, Student
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: locomotive_plugins
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.
|
4
|
+
version: 1.0.0.beta4
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-12-
|
12
|
+
date: 2012-12-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: locomotive_liquid
|
@@ -133,6 +133,7 @@ files:
|
|
133
133
|
- spec/support/plugins/plugin_with_filter.rb
|
134
134
|
- spec/support/plugins/plugin_with_many_filter_modules.rb
|
135
135
|
- spec/support/plugins/my_plugin.rb
|
136
|
+
- spec/support/plugins/plugin_with_db_model_relationships.rb
|
136
137
|
- spec/support/plugins/plugin_with_db_model.rb
|
137
138
|
- spec/support/factories.rb
|
138
139
|
- spec/fixtures/config_template.haml
|