datts_right 0.0.31 → 0.0.32
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/Gemfile.lock +1 -1
- data/VERSION +1 -1
- data/datts_right.gemspec +6 -2
- data/lib/datts_right/base.rb +34 -1
- data/lib/datts_right/category.rb +1 -1
- data/lib/datts_right/category_without_reflection.rb +4 -0
- data/lib/datts_right/instance_methods.rb +85 -47
- data/lib/datts_right/page_without_reflection.rb +9 -0
- data/spec/datts_right/definition_spec.rb +46 -0
- data/spec/datts_right/sync_definition_spec.rb +26 -0
- data/spec/datts_right_spec.rb +4 -0
- data/spec/spec_helper.rb +2 -0
- metadata +8 -4
data/Gemfile.lock
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.32
|
data/datts_right.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{datts_right}
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.32"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Ramon Tayag"]
|
12
|
-
s.date = %q{2011-04-
|
12
|
+
s.date = %q{2011-04-29}
|
13
13
|
s.description = %q{Creates a separate table that saves all your dynamic attributes.}
|
14
14
|
s.email = %q{ramon@tayag.net}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -31,12 +31,14 @@ Gem::Specification.new do |s|
|
|
31
31
|
"lib/datts_right.rb",
|
32
32
|
"lib/datts_right/base.rb",
|
33
33
|
"lib/datts_right/category.rb",
|
34
|
+
"lib/datts_right/category_without_reflection.rb",
|
34
35
|
"lib/datts_right/dynamic_attribute.rb",
|
35
36
|
"lib/datts_right/dynamic_attribute_definition.rb",
|
36
37
|
"lib/datts_right/errors.rb",
|
37
38
|
"lib/datts_right/exceptions.rb",
|
38
39
|
"lib/datts_right/instance_methods.rb",
|
39
40
|
"lib/datts_right/page.rb",
|
41
|
+
"lib/datts_right/page_without_reflection.rb",
|
40
42
|
"lib/datts_right/query_methods.rb",
|
41
43
|
"spec/datt_spec.rb",
|
42
44
|
"spec/datts_right/add_definition_spec.rb",
|
@@ -55,6 +57,7 @@ Gem::Specification.new do |s|
|
|
55
57
|
"spec/datts_right/remove_definition_spec.rb",
|
56
58
|
"spec/datts_right/remove_definitions_spec.rb",
|
57
59
|
"spec/datts_right/remove_dynamic_attribute_spec.rb",
|
60
|
+
"spec/datts_right/sync_definition_spec.rb",
|
58
61
|
"spec/datts_right/update_definition_spec.rb",
|
59
62
|
"spec/datts_right/update_definitions_spec.rb",
|
60
63
|
"spec/datts_right/where_dynamic_attribute_spec.rb",
|
@@ -87,6 +90,7 @@ Gem::Specification.new do |s|
|
|
87
90
|
"spec/datts_right/remove_definition_spec.rb",
|
88
91
|
"spec/datts_right/remove_definitions_spec.rb",
|
89
92
|
"spec/datts_right/remove_dynamic_attribute_spec.rb",
|
93
|
+
"spec/datts_right/sync_definition_spec.rb",
|
90
94
|
"spec/datts_right/update_definition_spec.rb",
|
91
95
|
"spec/datts_right/update_definitions_spec.rb",
|
92
96
|
"spec/datts_right/where_dynamic_attribute_spec.rb",
|
data/lib/datts_right/base.rb
CHANGED
@@ -8,7 +8,7 @@ module DattsRight
|
|
8
8
|
has_many :dynamic_attributes, :as => :attributable, :dependent => :destroy
|
9
9
|
has_one :dynamic_attribute_definition, :as => :attribute_defineable, :dependent => :destroy
|
10
10
|
after_save :save_dynamic_attribute_definition
|
11
|
-
after_create :create_dynamic_attribute_definition_if_needed, :inherit_definition
|
11
|
+
after_create :create_dynamic_attribute_definition_if_needed, :inherit_definition!
|
12
12
|
delegate :definition, :definition=, :to => :dynamic_attribute_definition
|
13
13
|
|
14
14
|
# Carry out delayed actions before save
|
@@ -17,6 +17,7 @@ module DattsRight
|
|
17
17
|
after_find :cache_dynamic_attributes
|
18
18
|
default_scope includes(:dynamic_attributes).includes(:dynamic_attribute_definition)
|
19
19
|
|
20
|
+
#validate :must_be_reflected_by_definer
|
20
21
|
|
21
22
|
# scope :scope_self when looking through attributes so we don't look through all dynamic_attributes
|
22
23
|
# Why? What if you have Friend and Page models.
|
@@ -74,6 +75,38 @@ module DattsRight
|
|
74
75
|
end
|
75
76
|
end
|
76
77
|
|
78
|
+
def self.defines?(klass=nil)
|
79
|
+
return false unless !dynamic_attributes_options[:defines].nil? && !dynamic_attributes_options[:defines].empty?
|
80
|
+
#puts "There is [:defines], and it's not empty"
|
81
|
+
if klass
|
82
|
+
klass = klass.class unless klass.is_a?(Class)
|
83
|
+
klass_symbol = klass.name.downcase.to_sym
|
84
|
+
dynamic_attributes_options[:defines].include?(klass_symbol)
|
85
|
+
else
|
86
|
+
true
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.defines
|
91
|
+
dynamic_attributes_options[:defines] if defines?
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.defined?
|
95
|
+
dynamic_attributes_options[:of]
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.defined_by?(arg)
|
99
|
+
return false unless self.defined?
|
100
|
+
symbol = if arg.is_a?(Class)
|
101
|
+
arg.name.underscore.to_sym
|
102
|
+
elsif arg.is_a?(Symbol)
|
103
|
+
arg
|
104
|
+
else # should be an instance
|
105
|
+
arg.class.name.underscore.to_sym
|
106
|
+
end
|
107
|
+
dynamic_attributes_options[:of] == symbol
|
108
|
+
end
|
109
|
+
|
77
110
|
private
|
78
111
|
|
79
112
|
def self.method_missing(method_id, *arguments)
|
data/lib/datts_right/category.rb
CHANGED
@@ -117,7 +117,7 @@ module DattsRight
|
|
117
117
|
end
|
118
118
|
|
119
119
|
def create_dynamic_attribute_definition_if_needed
|
120
|
-
if
|
120
|
+
if self.defines?
|
121
121
|
DynamicAttributeDefinition.create :attribute_defineable_id => self.id, :attribute_defineable_type => self.class.name, :definition => {}
|
122
122
|
end
|
123
123
|
end
|
@@ -126,7 +126,9 @@ module DattsRight
|
|
126
126
|
if key
|
127
127
|
key = key.to_sym
|
128
128
|
#puts "add_definition(:#{key}, #{value.inspect}). current definition: #{definition.nil?}"
|
129
|
-
if dynamic_attributes_options[:
|
129
|
+
if dynamic_attributes_options[:defines].nil? || dynamic_attributes_options[:defines].empty?
|
130
|
+
raise NoDefinitionError
|
131
|
+
else
|
130
132
|
#puts ":definition is true, so let's see if definition[:#{key}] already exists"
|
131
133
|
# Checking definition straight seems to cause a problem. Is this a bug with Rails?
|
132
134
|
# The problem was like this (assuming definition was actually nil):
|
@@ -142,8 +144,6 @@ module DattsRight
|
|
142
144
|
else
|
143
145
|
definition.merge!({key => value})
|
144
146
|
end
|
145
|
-
else
|
146
|
-
raise NoDefinitionError
|
147
147
|
end
|
148
148
|
else
|
149
149
|
raise AttributeKeyRequired
|
@@ -180,25 +180,20 @@ module DattsRight
|
|
180
180
|
end
|
181
181
|
|
182
182
|
def update_definition(key, new_values={})
|
183
|
-
|
184
|
-
|
185
|
-
attr_key = new_values.symbolize_keys[:attr_key]
|
186
|
-
new_values.each do |k, v|
|
187
|
-
definition[key][k] = v unless k.to_s == "attr_key"
|
188
|
-
end
|
183
|
+
raise NoDefinitionError unless self.defines?
|
184
|
+
raise NotDefinedError, "#{key} is not defined" unless definition && definition[key]
|
189
185
|
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
raise NoDefinitionError
|
186
|
+
attr_key = new_values.symbolize_keys[:attr_key]
|
187
|
+
new_values.each do |k, v|
|
188
|
+
definition[key][k] = v unless k.to_s == "attr_key"
|
189
|
+
end
|
190
|
+
|
191
|
+
#puts "attr_key is #{attr_key}, key is #{key}"
|
192
|
+
if attr_key && attr_key != key.to_s
|
193
|
+
#puts "Adding definition: #{attr_key} => #{definition[key]}"
|
194
|
+
add_definition(attr_key, definition[key])
|
195
|
+
#puts "Removing definition: #{key} => #{definition[key]}"
|
196
|
+
remove_definition(key)
|
202
197
|
end
|
203
198
|
end
|
204
199
|
|
@@ -211,15 +206,9 @@ module DattsRight
|
|
211
206
|
def remove_definition(key)
|
212
207
|
if key
|
213
208
|
key = key.to_sym
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
else
|
218
|
-
raise NotDefinedError, "#{key} is not defined"
|
219
|
-
end
|
220
|
-
else
|
221
|
-
raise NoDefinitionError
|
222
|
-
end
|
209
|
+
raise NoDefinitionError unless self.defines?
|
210
|
+
raise NotDefinedError, "#{key} is not defined" unless definition && definition[key]
|
211
|
+
definition.delete(key)
|
223
212
|
end
|
224
213
|
end
|
225
214
|
|
@@ -231,6 +220,71 @@ module DattsRight
|
|
231
220
|
end
|
232
221
|
end
|
233
222
|
|
223
|
+
# Adds dynamic attributes to inheriting model, based on the definition of the defining model.
|
224
|
+
# class InheritingModel < AR::Base
|
225
|
+
# has_dynamic_attributes :of => :defining_model
|
226
|
+
# end
|
227
|
+
#
|
228
|
+
# The DefiningModel should have the code:
|
229
|
+
# class DefiningModel < AR::Base
|
230
|
+
# has_dynamic_attributes :defines => [:inheriting_model]
|
231
|
+
# end
|
232
|
+
#
|
233
|
+
# Example:
|
234
|
+
# @defining_model.add_definitions(:name => {:object_type => "string"}, :body => {:object_type => "text"})
|
235
|
+
# @defining_model.save
|
236
|
+
# InheritingModel.create # creates an instance with dynamic attributes: name and body, that are "string" and "text", respectively
|
237
|
+
#
|
238
|
+
# Calling this method manually only _adds_ to the inheriting instance you call it on. If you remove some definitions from the defining model, then you call @inheriting_model.inherit_definition!@, the new definitions will be added. If there are no new definitions, nothing will happen.
|
239
|
+
def inherit_definition!
|
240
|
+
#puts "In inherit_definition"
|
241
|
+
#puts "------- #{dynamic_attributes_options[:of]}"
|
242
|
+
#dynamic_attribute_definition.create if dynamic_attributes_options[:definition]
|
243
|
+
if self.defined? && defining_record
|
244
|
+
defining_record.definition.each do |k, v|
|
245
|
+
datt = add_dynamic_attribute(k, v[:object_type])
|
246
|
+
datt.dynamic_attribute_definition
|
247
|
+
#puts "Added #{datt.inspect}"
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
# Adds and removes dynamic attributes based on the defining record
|
253
|
+
def sync_definition!
|
254
|
+
defining_record.definition.each do |k, v|
|
255
|
+
add_dynamic_attribute(k, v[:object_type]) if dynamic_attribute_details(k).nil?
|
256
|
+
end
|
257
|
+
@dynamic_attributes_cache.each do |k, v|
|
258
|
+
#puts "Remove #{k}?"
|
259
|
+
remove_dynamic_attribute(k) if v.definer.nil?
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
# Returns true if this defines any other class
|
264
|
+
def defines?(klass=nil)
|
265
|
+
self.class.defines?(klass)
|
266
|
+
end
|
267
|
+
|
268
|
+
# Returns true if this is defined by any other class
|
269
|
+
def defined?
|
270
|
+
self.class.defined?
|
271
|
+
end
|
272
|
+
|
273
|
+
# Returns true if the calling instance is defined by the argument
|
274
|
+
def defined_by?(arg)
|
275
|
+
self.class.defined_by?(arg)
|
276
|
+
end
|
277
|
+
|
278
|
+
# Returns an array of symbols of the classes that this defines
|
279
|
+
def defines
|
280
|
+
self.class.defines
|
281
|
+
end
|
282
|
+
|
283
|
+
#def must_be_reflected_by_definer
|
284
|
+
#errors.add(:base, "#{self.class.name} inherits its definition from #{dynamic_attributes_options[:of]} but that does not define #{self.class.name}.") \
|
285
|
+
#unless dynamic_attributes_options[:of].to_s.classify.constantize.defines?(self.class)
|
286
|
+
#end
|
287
|
+
|
234
288
|
private
|
235
289
|
|
236
290
|
# Called after validation on update so that dynamic attributes behave
|
@@ -267,22 +321,6 @@ module DattsRight
|
|
267
321
|
dynamic_attribute_definition.save if dynamic_attribute_definition
|
268
322
|
end
|
269
323
|
|
270
|
-
def inherit_definition
|
271
|
-
#puts "In inherit_definition"
|
272
|
-
#puts "------- #{dynamic_attributes_options[:of]}"
|
273
|
-
#dynamic_attribute_definition.create if dynamic_attributes_options[:definition]
|
274
|
-
if dynamic_attributes_options[:of]
|
275
|
-
#puts "There is a defining record of #{self.class.name}##{self.name} in #{defining_record.inspect}. #{defining_record.dynamic_attribute_definition.inspect}"
|
276
|
-
if defining_record
|
277
|
-
defining_record.definition.each do |k, v|
|
278
|
-
datt = add_dynamic_attribute(k, v[:object_type])
|
279
|
-
datt.dynamic_attribute_definition
|
280
|
-
#puts "Added #{datt.inspect}"
|
281
|
-
end
|
282
|
-
end
|
283
|
-
end
|
284
|
-
end
|
285
|
-
|
286
324
|
alias :add_datt :add_dynamic_attribute
|
287
325
|
alias :add_datt! :add_dynamic_attribute!
|
288
326
|
alias :remove_datt :remove_dynamic_attribute
|
@@ -0,0 +1,9 @@
|
|
1
|
+
class PageWithoutReflection < ActiveRecord::Base
|
2
|
+
set_table_name "pages"
|
3
|
+
belongs_to :category_without_reflection
|
4
|
+
has_dynamic_attributes :of => :category_without_reflection
|
5
|
+
|
6
|
+
def virtual_attribute=(something)
|
7
|
+
puts "Setting virtual_attribute to #{something}"
|
8
|
+
end
|
9
|
+
end
|
@@ -4,4 +4,50 @@ describe DattsRight, "on the definition" do
|
|
4
4
|
it "should not be created if it is not defined" do
|
5
5
|
Page.create.dynamic_attribute_definition.should be_nil
|
6
6
|
end
|
7
|
+
|
8
|
+
describe ".defines?" do
|
9
|
+
it "should return true if nil is passed, and it has the option and it's not empty" do
|
10
|
+
Category.defines?.should be_true
|
11
|
+
Category.new.defines?.should be_true
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should return true if a class is passed, it has the option, and it defines the class" do
|
15
|
+
Category.defines?(Page).should be_true
|
16
|
+
Category.new.defines?(Page).should be_true
|
17
|
+
Category.defines?(Page.new).should be_true
|
18
|
+
Category.new.defines?(Page.new).should be_true
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe ".defines" do
|
23
|
+
it "should return the array of classes that it defines" do
|
24
|
+
Category.defines.should == [:page]
|
25
|
+
Category.new.defines.should == [:page]
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should return nil if it does not define anything" do
|
29
|
+
Page.defines.should be_nil
|
30
|
+
Page.new.defines.should be_nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe ".defined?" do
|
35
|
+
it "should return true if it has the option and it's not empty" do
|
36
|
+
Page.defined?.should be_true
|
37
|
+
Page.new.defined?.should be_true
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe ".defined_by?(klass_or_instance)" do
|
42
|
+
it "should return true if a class is passed, it has the option, and it defines the class" do
|
43
|
+
Page.defined_by?(Category).should be_true
|
44
|
+
Page.defined_by?(Category.new).should be_true
|
45
|
+
Page.defined_by?(:category).should be_true
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should be the same as the instance method" do
|
49
|
+
Page.should_receive(:defined_by?).with(Category)
|
50
|
+
Page.new.defined_by?(Category)
|
51
|
+
end
|
52
|
+
end
|
7
53
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe DattsRight, ".sync_definition!" do
|
4
|
+
before do
|
5
|
+
reset_database
|
6
|
+
@category = Category.create
|
7
|
+
@category.definition = {:teaser => {:object_type => "text"}, :body => {:object_type => "text"}}
|
8
|
+
@category.save
|
9
|
+
@page = Page.create :category => @category
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should add any new definitions" do
|
13
|
+
@category.add_definition(:price, {:object_type => "integer"})
|
14
|
+
@category.save
|
15
|
+
@page.sync_definition!
|
16
|
+
@page.dynamic_attribute_details(:price)[:object_type].should == "integer"
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should remove any dynamic attributes if the definitions are removed" do
|
20
|
+
@category.remove_definition(:body)
|
21
|
+
@category.save
|
22
|
+
@page.sync_definition!
|
23
|
+
@page.dynamic_attribute_details(:teaser)[:object_type].should == "text"
|
24
|
+
lambda {@page.body}.should raise_error(NoMethodError)
|
25
|
+
end
|
26
|
+
end
|
data/spec/datts_right_spec.rb
CHANGED
@@ -178,4 +178,8 @@ describe DattsRight do
|
|
178
178
|
it "should still allow virtual attributes to work (for mass assignment)" do
|
179
179
|
lambda {Category.create.update_attributes(:definition_attributes => {"attr_key" => "some_attr", "object_type" => "string"}, :name => "hello")}.should_not raise_error(ActiveRecord::UnknownAttributeError)
|
180
180
|
end
|
181
|
+
|
182
|
+
#it "should validate reflection of inheritance" do
|
183
|
+
#PageWithoutReflection.new.errors[:base].should include("Page inherits its definition from category_without_reflection but that does not define Page.")
|
184
|
+
#end
|
181
185
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -6,7 +6,9 @@ require 'active_record/errors'
|
|
6
6
|
require 'rspec'
|
7
7
|
require 'datts_right'
|
8
8
|
require 'datts_right/page'
|
9
|
+
require 'datts_right/page_without_reflection'
|
9
10
|
require 'datts_right/category'
|
11
|
+
require 'datts_right/category_without_reflection'
|
10
12
|
|
11
13
|
# Allow to connect to SQLite
|
12
14
|
root = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: datts_right
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 95
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 32
|
10
|
+
version: 0.0.32
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Ramon Tayag
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-04-
|
18
|
+
date: 2011-04-29 00:00:00 +08:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -162,12 +162,14 @@ files:
|
|
162
162
|
- lib/datts_right.rb
|
163
163
|
- lib/datts_right/base.rb
|
164
164
|
- lib/datts_right/category.rb
|
165
|
+
- lib/datts_right/category_without_reflection.rb
|
165
166
|
- lib/datts_right/dynamic_attribute.rb
|
166
167
|
- lib/datts_right/dynamic_attribute_definition.rb
|
167
168
|
- lib/datts_right/errors.rb
|
168
169
|
- lib/datts_right/exceptions.rb
|
169
170
|
- lib/datts_right/instance_methods.rb
|
170
171
|
- lib/datts_right/page.rb
|
172
|
+
- lib/datts_right/page_without_reflection.rb
|
171
173
|
- lib/datts_right/query_methods.rb
|
172
174
|
- spec/datt_spec.rb
|
173
175
|
- spec/datts_right/add_definition_spec.rb
|
@@ -186,6 +188,7 @@ files:
|
|
186
188
|
- spec/datts_right/remove_definition_spec.rb
|
187
189
|
- spec/datts_right/remove_definitions_spec.rb
|
188
190
|
- spec/datts_right/remove_dynamic_attribute_spec.rb
|
191
|
+
- spec/datts_right/sync_definition_spec.rb
|
189
192
|
- spec/datts_right/update_definition_spec.rb
|
190
193
|
- spec/datts_right/update_definitions_spec.rb
|
191
194
|
- spec/datts_right/where_dynamic_attribute_spec.rb
|
@@ -246,6 +249,7 @@ test_files:
|
|
246
249
|
- spec/datts_right/remove_definition_spec.rb
|
247
250
|
- spec/datts_right/remove_definitions_spec.rb
|
248
251
|
- spec/datts_right/remove_dynamic_attribute_spec.rb
|
252
|
+
- spec/datts_right/sync_definition_spec.rb
|
249
253
|
- spec/datts_right/update_definition_spec.rb
|
250
254
|
- spec/datts_right/update_definitions_spec.rb
|
251
255
|
- spec/datts_right/where_dynamic_attribute_spec.rb
|