json_record 1.1.0.b2 → 1.1.0.b6
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/CHANGE_LOG +0 -3
- data/Rakefile +5 -8
- data/VERSION +1 -1
- data/json_record.gemspec +4 -4
- data/lib/json_record.rb +10 -14
- data/lib/json_record/attribute_methods.rb +1 -1
- data/lib/json_record/embedded_document.rb +23 -99
- data/lib/json_record/embedded_document_array.rb +5 -0
- data/lib/json_record/field_definition.rb +1 -1
- data/lib/json_record/json_field.rb +1 -1
- data/lib/json_record/schema.rb +2 -0
- data/lib/json_record/serialized.rb +16 -1
- data/spec/embedded_document_array_spec.rb +1 -0
- data/spec/serialized_spec.rb +13 -0
- data/spec/spec_helper.rb +2 -3
- metadata +15 -4
data/CHANGE_LOG
CHANGED
data/Rakefile
CHANGED
@@ -12,8 +12,8 @@ begin
|
|
12
12
|
t.spec_files = FileList.new('spec/**/*_spec.rb')
|
13
13
|
end
|
14
14
|
rescue LoadError
|
15
|
-
|
16
|
-
STDERR.puts "You must have rspec >= 1.
|
15
|
+
tast :test do
|
16
|
+
STDERR.puts "You must have rspec >= 1.3.0 to run the tests"
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
@@ -33,15 +33,12 @@ begin
|
|
33
33
|
gem.email = "brian@embellishedvisions.com"
|
34
34
|
gem.homepage = "http://github.com/bdurand/json_record"
|
35
35
|
gem.authors = ["Brian Durand"]
|
36
|
-
gem.files = FileList["lib/**/*", "spec/**/*", "README.rdoc", "Rakefile"].to_a
|
37
|
-
gem.has_rdoc = true
|
38
|
-
gem.extra_rdoc_files = ["README.rdoc"]
|
39
36
|
|
40
|
-
gem.add_dependency('activerecord', '>=
|
41
|
-
gem.add_development_dependency('rspec', '>= 1.
|
37
|
+
gem.add_dependency('activerecord', '>= 3.0.0.beta2')
|
38
|
+
gem.add_development_dependency('rspec', '>= 1.3.0')
|
42
39
|
gem.add_development_dependency('jeweler')
|
43
40
|
end
|
44
41
|
|
45
42
|
Jeweler::GemcutterTasks.new
|
46
43
|
rescue LoadError
|
47
|
-
end
|
44
|
+
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.
|
1
|
+
1.1.0.b6
|
data/json_record.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{json_record}
|
8
|
-
s.version = "1.1.0.
|
8
|
+
s.version = "1.1.0.b6"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Brian Durand"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-05-25}
|
13
13
|
s.email = %q{brian@embellishedvisions.com}
|
14
14
|
s.extra_rdoc_files = [
|
15
15
|
"README.rdoc"
|
@@ -40,7 +40,7 @@ Gem::Specification.new do |s|
|
|
40
40
|
s.homepage = %q{http://github.com/bdurand/json_record}
|
41
41
|
s.rdoc_options = ["--charset=UTF-8"]
|
42
42
|
s.require_paths = ["lib"]
|
43
|
-
s.rubygems_version = %q{1.3.
|
43
|
+
s.rubygems_version = %q{1.3.7}
|
44
44
|
s.summary = %q{ActiveRecord support for mapping complex documents in a single RDBMS row via JSON serialization.}
|
45
45
|
s.test_files = [
|
46
46
|
"spec/embedded_document_array_spec.rb",
|
@@ -55,7 +55,7 @@ Gem::Specification.new do |s|
|
|
55
55
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
56
56
|
s.specification_version = 3
|
57
57
|
|
58
|
-
if Gem::Version.new(Gem::
|
58
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
59
59
|
s.add_runtime_dependency(%q<activerecord>, [">= 3.0.0.beta2"])
|
60
60
|
s.add_development_dependency(%q<rspec>, [">= 1.3.0"])
|
61
61
|
s.add_development_dependency(%q<jeweler>, [">= 0"])
|
data/lib/json_record.rb
CHANGED
@@ -1,22 +1,18 @@
|
|
1
1
|
require 'active_record'
|
2
2
|
|
3
|
-
begin
|
4
|
-
require 'json'
|
5
|
-
rescue LoadError
|
6
|
-
ActiveRecord::Base.logger.warn("*** You really should install the json gem for optimal performance with json_record ***")
|
7
|
-
end
|
8
|
-
|
9
3
|
unless defined?(Boolean)
|
10
4
|
class Boolean
|
11
5
|
end
|
12
6
|
end
|
13
7
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
8
|
+
module JsonRecord
|
9
|
+
autoload :Schema, File.expand_path(File.join(File.dirname(__FILE__), 'json_record', 'schema'))
|
10
|
+
autoload :AttributeMethods, File.expand_path(File.join(File.dirname(__FILE__), 'json_record', 'attribute_methods'))
|
11
|
+
autoload :EmbeddedDocument, File.expand_path(File.join(File.dirname(__FILE__), 'json_record', 'embedded_document'))
|
12
|
+
autoload :EmbeddedDocumentArray, File.expand_path(File.join(File.dirname(__FILE__), 'json_record', 'embedded_document_array'))
|
13
|
+
autoload :FieldDefinition, File.expand_path(File.join(File.dirname(__FILE__), 'json_record', 'field_definition'))
|
14
|
+
autoload :JsonField, File.expand_path(File.join(File.dirname(__FILE__), 'json_record', 'json_field'))
|
15
|
+
autoload :Serialized, File.expand_path(File.join(File.dirname(__FILE__), 'json_record', 'serialized'))
|
16
|
+
end
|
21
17
|
|
22
|
-
ActiveRecord::Base.send(:include, JsonRecord::Serialized)
|
18
|
+
ActiveRecord::Base.send(:include, JsonRecord::Serialized)
|
@@ -1,52 +1,4 @@
|
|
1
1
|
module JsonRecord
|
2
|
-
# OK, this is ugly, but necessary to get ActiveRecord::Errors to be compatible with
|
3
|
-
# EmbeddedDocument. This will all be fixed with Rails 3 and ActiveModel. Until then
|
4
|
-
# we'll just live with this.
|
5
|
-
module ActiveRecordStub #:nodoc:
|
6
|
-
def self.included (base)
|
7
|
-
base.extend(ClassMethods)
|
8
|
-
end
|
9
|
-
|
10
|
-
module ClassMethods
|
11
|
-
def human_name (options = {})
|
12
|
-
name.split('::').last.humanize
|
13
|
-
end
|
14
|
-
|
15
|
-
def human_attribute_name (attribute, options = {})
|
16
|
-
attribute.to_s.humanize
|
17
|
-
end
|
18
|
-
|
19
|
-
def self_and_descendants_from_active_record
|
20
|
-
[self]
|
21
|
-
end
|
22
|
-
|
23
|
-
def self_and_descendents_from_active_record
|
24
|
-
[self]
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def deprecated_callback_method (*args)
|
29
|
-
end
|
30
|
-
|
31
|
-
private
|
32
|
-
def save (*args); end;
|
33
|
-
def save! (*args); end;
|
34
|
-
def destroy (*args); end;
|
35
|
-
def create (*args); end;
|
36
|
-
def update (*args); end;
|
37
|
-
def new_record?; false; end;
|
38
|
-
end
|
39
|
-
|
40
|
-
module ActiveSupport3Callbacks #:nodoc:
|
41
|
-
def before_validation (*args, &block)
|
42
|
-
set_callback(:validation, :before, *args, &block)
|
43
|
-
end
|
44
|
-
|
45
|
-
def after_validation (*args, &block)
|
46
|
-
set_callback(:validation, :after, *args, &block)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
2
|
# Classes that include EmbeddedDocument can be used as the type for keys or many field definitions
|
51
3
|
# in Schema. Embedded documents are then extensions of the schema. In this way, complex
|
52
4
|
# documents represented in JSON can be deserialized as complex objects.
|
@@ -54,27 +6,30 @@ module JsonRecord
|
|
54
6
|
# To define the schema for an embedded document, call schema.key or schema.many from the class definition.
|
55
7
|
module EmbeddedDocument
|
56
8
|
def self.included (base)
|
57
|
-
base.send :include,
|
58
|
-
base.send :include,
|
9
|
+
base.send :include, ActiveModel::AttributeMethods
|
10
|
+
base.send :include, ActiveModel::Dirty
|
11
|
+
base.send :include, ActiveModel::Validations
|
59
12
|
base.send :include, AttributeMethods
|
60
13
|
base.send :include, ActiveSupport::Callbacks
|
61
14
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
# Incoporating ActiveModel will fix all.
|
66
|
-
base.define_callbacks :validation
|
67
|
-
base.alias_method_chain(:valid?, :callbacks_3)
|
68
|
-
base.extend(ActiveSupport3Callbacks)
|
69
|
-
else
|
70
|
-
base.define_callbacks :before_validation, :after_validation
|
71
|
-
base.alias_method_chain(:valid?, :callbacks)
|
72
|
-
end
|
15
|
+
base.define_callbacks :validation
|
16
|
+
base.alias_method_chain(:valid?, :callbacks)
|
17
|
+
base.extend ValidationCallbacks
|
73
18
|
|
74
19
|
base.write_inheritable_attribute(:schema, Schema.new(base, nil))
|
75
20
|
base.class_inheritable_reader :schema
|
76
21
|
end
|
77
22
|
|
23
|
+
module ValidationCallbacks #:nodoc:
|
24
|
+
def before_validation (*args, &block)
|
25
|
+
set_callback(:validation, :before, *args, &block)
|
26
|
+
end
|
27
|
+
|
28
|
+
def after_validation (*args, &block)
|
29
|
+
set_callback(:validation, :after, *args, &block)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
78
33
|
# The parent object of the document.
|
79
34
|
attr_accessor :parent
|
80
35
|
|
@@ -105,22 +60,7 @@ module JsonRecord
|
|
105
60
|
|
106
61
|
# Get the attribute values of the document before they were type cast.
|
107
62
|
def attributes_before_type_cast
|
108
|
-
|
109
|
-
end
|
110
|
-
|
111
|
-
# Determine if the document has been changed.
|
112
|
-
def changed?
|
113
|
-
!changed_attributes.empty?
|
114
|
-
end
|
115
|
-
|
116
|
-
# Get the list of attributes changed.
|
117
|
-
def changed
|
118
|
-
changed_attributes.keys
|
119
|
-
end
|
120
|
-
|
121
|
-
# Get a list of changes to the document.
|
122
|
-
def changes
|
123
|
-
changed.inject({}) {|h, attr| h[attr] = attribute_change(attr); h}
|
63
|
+
json_attributes_before_type_cast
|
124
64
|
end
|
125
65
|
|
126
66
|
# Get a field from the schema with the specified name.
|
@@ -156,15 +96,8 @@ module JsonRecord
|
|
156
96
|
end
|
157
97
|
|
158
98
|
def valid_with_callbacks? #:nodoc:
|
159
|
-
run_callbacks(:before_validation)
|
160
|
-
valid = valid_without_callbacks?
|
161
|
-
run_callbacks(:after_validation)
|
162
|
-
valid
|
163
|
-
end
|
164
|
-
|
165
|
-
def valid_with_callbacks_3? #:nodoc:
|
166
99
|
run_callbacks(:validation) do
|
167
|
-
|
100
|
+
valid_without_callbacks?
|
168
101
|
end
|
169
102
|
end
|
170
103
|
|
@@ -174,6 +107,10 @@ module JsonRecord
|
|
174
107
|
@json_attributes
|
175
108
|
end
|
176
109
|
|
110
|
+
def json_attributes_before_type_cast
|
111
|
+
@attributes
|
112
|
+
end
|
113
|
+
|
177
114
|
def read_json_attribute (json_field_name, field)
|
178
115
|
read_attribute(field, self)
|
179
116
|
end
|
@@ -181,7 +118,7 @@ module JsonRecord
|
|
181
118
|
def write_json_attribute (json_field_name, field, value)
|
182
119
|
write_attribute(field, value, self)
|
183
120
|
end
|
184
|
-
|
121
|
+
|
185
122
|
def changed_attributes
|
186
123
|
@changed_attributes ||= {}
|
187
124
|
end
|
@@ -189,18 +126,5 @@ module JsonRecord
|
|
189
126
|
def read_attribute_before_type_cast (name)
|
190
127
|
@attributes[name.to_s]
|
191
128
|
end
|
192
|
-
|
193
|
-
def attribute_changed? (name)
|
194
|
-
changed_attributes.include?(name.to_s)
|
195
|
-
end
|
196
|
-
|
197
|
-
def attribute_change (name)
|
198
|
-
name = name.to_s
|
199
|
-
[changed_attributes[name], read_json_attribute(nil, schema.fields[name])] if attribute_changed?(name)
|
200
|
-
end
|
201
|
-
|
202
|
-
def attribute_was (name)
|
203
|
-
changed_attributes[name.to_s]
|
204
|
-
end
|
205
129
|
end
|
206
130
|
end
|
data/lib/json_record/schema.rb
CHANGED
@@ -131,6 +131,8 @@ module JsonRecord
|
|
131
131
|
@klass.send(:define_method, "#{field.name}_changed?") {self.send(:attribute_changed?, field.name)}
|
132
132
|
@klass.send(:define_method, "#{field.name}_change") {self.send(:attribute_change, field.name)}
|
133
133
|
@klass.send(:define_method, "#{field.name}_was") {self.send(:attribute_was, field.name)}
|
134
|
+
@klass.send(:define_method, "#{field.name}_will_change!") {self.send(:attribute_will_change!, field.name)}
|
135
|
+
@klass.send(:define_method, "reset_#{field.name}!") {self.send(:reset_attribute!, field.name)}
|
134
136
|
end
|
135
137
|
end
|
136
138
|
|
@@ -53,6 +53,8 @@ module JsonRecord
|
|
53
53
|
base.alias_method_chain :attributes, :serialized_json
|
54
54
|
base.alias_method_chain :read_attribute, :serialized_json
|
55
55
|
base.alias_method_chain :write_attribute, :serialized_json
|
56
|
+
base.alias_method_chain :read_attribute_before_type_cast, :serialized_json
|
57
|
+
base.alias_method_chain :attributes_before_type_cast, :serialized_json
|
56
58
|
end
|
57
59
|
|
58
60
|
# Get the JsonField objects for the record.
|
@@ -66,8 +68,13 @@ module JsonRecord
|
|
66
68
|
@json_fields
|
67
69
|
end
|
68
70
|
|
71
|
+
def json_attributes_before_type_cast # :nodoc:
|
72
|
+
@json_attributes_before_type_cast ||= {}
|
73
|
+
end
|
74
|
+
|
69
75
|
def reload_with_serialized_json (*args) #:nodoc:
|
70
76
|
@json_fields = nil
|
77
|
+
@json_attributes_before_type_cast = nil
|
71
78
|
reload_without_serialized_json(*args)
|
72
79
|
end
|
73
80
|
|
@@ -78,6 +85,14 @@ module JsonRecord
|
|
78
85
|
return attrs
|
79
86
|
end
|
80
87
|
|
88
|
+
def read_attribute_before_type_cast_with_serialized_json (attr_name) #:nodoc:
|
89
|
+
json_attributes_before_type_cast[attr_name.to_s] || read_attribute_before_type_cast_without_serialized_json(attr_name)
|
90
|
+
end
|
91
|
+
|
92
|
+
def attributes_before_type_cast_with_serialized_json #:nodoc:
|
93
|
+
json_attributes_before_type_cast.merge(attributes_before_type_cast_without_serialized_json)
|
94
|
+
end
|
95
|
+
|
81
96
|
def read_attribute_with_serialized_json (name)
|
82
97
|
name = name.to_s
|
83
98
|
json_field, field_definition = self.class.json_field_definition(name)
|
@@ -109,7 +124,7 @@ module JsonRecord
|
|
109
124
|
attrs
|
110
125
|
end
|
111
126
|
|
112
|
-
def json_field_names
|
127
|
+
def json_field_names # :nodoc:
|
113
128
|
@json_field_names = json_serialized_fields.values.flatten.collect{|s| s.fields.keys}.flatten
|
114
129
|
end
|
115
130
|
|
data/spec/serialized_spec.rb
CHANGED
@@ -259,6 +259,19 @@ describe JsonRecord::Serialized do
|
|
259
259
|
model.name_changed?.should be_blank
|
260
260
|
model.name_was.should == "test name"
|
261
261
|
model.name_change.should == nil
|
262
|
+
|
263
|
+
model.reset_value!
|
264
|
+
model.value_changed?.should == false
|
265
|
+
model.value.should == 0
|
266
|
+
|
267
|
+
model.value_will_change!
|
268
|
+
model.value_changed?.should == true
|
269
|
+
end
|
270
|
+
|
271
|
+
it "should track the value before type casting on json attributes" do
|
272
|
+
model = JsonRecord::Test::Model.new(:name => "test", :value => "1")
|
273
|
+
model.name_before_type_cast.should == "test"
|
274
|
+
model.value_before_type_cast.should == "1"
|
262
275
|
end
|
263
276
|
|
264
277
|
it "should validate the presence of a json attribute" do
|
data/spec/spec_helper.rb
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
|
3
|
-
active_record_version = ENV["ACTIVE_RECORD_VERSION"] || [">=
|
3
|
+
active_record_version = ENV["ACTIVE_RECORD_VERSION"] || [">= 3.0.0.beta2"]
|
4
4
|
active_record_version = [active_record_version] unless active_record_version.is_a?(Array)
|
5
5
|
gem 'activerecord', *active_record_version
|
6
6
|
|
7
7
|
require 'spec'
|
8
8
|
require 'active_record'
|
9
|
-
puts "Testing Against ActiveRecord #{ActiveRecord::VERSION::STRING}"
|
10
|
-
ActiveRecord.load_all! if ActiveRecord.respond_to?(:load_all!)
|
9
|
+
puts "Testing Against ActiveRecord #{ActiveRecord::VERSION::STRING}"
|
11
10
|
|
12
11
|
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'json_record'))
|
13
12
|
require File.expand_path(File.join(File.dirname(__FILE__), 'test_models'))
|
metadata
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: json_record
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 6629696
|
4
5
|
prerelease: true
|
5
6
|
segments:
|
6
7
|
- 1
|
7
8
|
- 1
|
8
9
|
- 0
|
9
|
-
-
|
10
|
-
version: 1.1.0.
|
10
|
+
- b6
|
11
|
+
version: 1.1.0.b6
|
11
12
|
platform: ruby
|
12
13
|
authors:
|
13
14
|
- Brian Durand
|
@@ -15,16 +16,18 @@ autorequire:
|
|
15
16
|
bindir: bin
|
16
17
|
cert_chain: []
|
17
18
|
|
18
|
-
date: 2010-
|
19
|
+
date: 2010-05-25 00:00:00 -05:00
|
19
20
|
default_executable:
|
20
21
|
dependencies:
|
21
22
|
- !ruby/object:Gem::Dependency
|
22
23
|
name: activerecord
|
23
24
|
prerelease: false
|
24
25
|
requirement: &id001 !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
25
27
|
requirements:
|
26
28
|
- - ">="
|
27
29
|
- !ruby/object:Gem::Version
|
30
|
+
hash: -1848230022
|
28
31
|
segments:
|
29
32
|
- 3
|
30
33
|
- 0
|
@@ -37,9 +40,11 @@ dependencies:
|
|
37
40
|
name: rspec
|
38
41
|
prerelease: false
|
39
42
|
requirement: &id002 !ruby/object:Gem::Requirement
|
43
|
+
none: false
|
40
44
|
requirements:
|
41
45
|
- - ">="
|
42
46
|
- !ruby/object:Gem::Version
|
47
|
+
hash: 27
|
43
48
|
segments:
|
44
49
|
- 1
|
45
50
|
- 3
|
@@ -51,9 +56,11 @@ dependencies:
|
|
51
56
|
name: jeweler
|
52
57
|
prerelease: false
|
53
58
|
requirement: &id003 !ruby/object:Gem::Requirement
|
59
|
+
none: false
|
54
60
|
requirements:
|
55
61
|
- - ">="
|
56
62
|
- !ruby/object:Gem::Version
|
63
|
+
hash: 3
|
57
64
|
segments:
|
58
65
|
- 0
|
59
66
|
version: "0"
|
@@ -99,16 +106,20 @@ rdoc_options:
|
|
99
106
|
require_paths:
|
100
107
|
- lib
|
101
108
|
required_ruby_version: !ruby/object:Gem::Requirement
|
109
|
+
none: false
|
102
110
|
requirements:
|
103
111
|
- - ">="
|
104
112
|
- !ruby/object:Gem::Version
|
113
|
+
hash: 3
|
105
114
|
segments:
|
106
115
|
- 0
|
107
116
|
version: "0"
|
108
117
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
118
|
+
none: false
|
109
119
|
requirements:
|
110
120
|
- - ">"
|
111
121
|
- !ruby/object:Gem::Version
|
122
|
+
hash: 25
|
112
123
|
segments:
|
113
124
|
- 1
|
114
125
|
- 3
|
@@ -117,7 +128,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
117
128
|
requirements: []
|
118
129
|
|
119
130
|
rubyforge_project:
|
120
|
-
rubygems_version: 1.3.
|
131
|
+
rubygems_version: 1.3.7
|
121
132
|
signing_key:
|
122
133
|
specification_version: 3
|
123
134
|
summary: ActiveRecord support for mapping complex documents in a single RDBMS row via JSON serialization.
|