json_record 1.0.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +5 -3
- data/VERSION +1 -1
- data/json_record.gemspec +1 -1
- data/lib/json_record/embedded_document.rb +11 -21
- data/lib/json_record/serialized.rb +10 -5
- data/lib/json_record.rb +2 -0
- data/spec/serialized_spec.rb +2 -1
- data/spec/test_models.rb +13 -6
- metadata +1 -1
data/README.rdoc
CHANGED
@@ -17,7 +17,7 @@ This will define for you accessors on your model for name and value and serializ
|
|
17
17
|
|
18
18
|
== Embedded Documents
|
19
19
|
|
20
|
-
To make you flexible schema really powerful, add some embedded documents to it. Embedded documents are Ruby classes that
|
20
|
+
To make you flexible schema really powerful, add some embedded documents to it. Embedded documents are Ruby classes that include JsonRecord::EmbeddedDocument. They work very much like traditional ActiveRecord objects, except that instead of being serialized in a separate table, they are embedded right in the JSON field of their parent record. They can be used to replace has_many and has_one associations and can be far easier to work with.
|
21
21
|
|
22
22
|
Embedded documents have their own schema that is serialized to JSON. This schema can also contain embedded documents allowing you to easily create very rich data structures all with only one database table. And because there is only one table, you don't need to worry at all about ensuring your changes to embedded documents are saved along with the parent record.
|
23
23
|
|
@@ -32,12 +32,14 @@ Embedded documents have their own schema that is serialized to JSON. This schema
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
-
class Person
|
35
|
+
class Person
|
36
|
+
include JsonRecord::EmbeddedDocument
|
36
37
|
schema.key :first_name, :required => true
|
37
38
|
schema.key :last_name
|
38
39
|
end
|
39
40
|
|
40
|
-
class Comment
|
41
|
+
class Comment
|
42
|
+
include JsonRecord::EmbeddedDocument
|
41
43
|
schema.key :author, Person, :required => true
|
42
44
|
schema.key :body, :required => true
|
43
45
|
schema.many :replies, Comment
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.
|
1
|
+
1.0.2
|
data/json_record.gemspec
CHANGED
@@ -37,29 +37,19 @@ module JsonRecord
|
|
37
37
|
def new_record?; false; end;
|
38
38
|
end
|
39
39
|
|
40
|
-
#
|
40
|
+
# Classes that include EmbeddedDocument can be used as the type for keys or many field definitions
|
41
41
|
# in Schema. Embedded documents are then extensions of the schema. In this way, complex
|
42
42
|
# documents represented in JSON can be deserialized as complex objects.
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
# See Schema#key for details.
|
54
|
-
def key (name, *args)
|
55
|
-
schema.key(name, *args)
|
56
|
-
end
|
57
|
-
|
58
|
-
# Define a multivalued field for the schema. This is a shortcut for calling schema.many.
|
59
|
-
# See Schema#many for details.
|
60
|
-
def many (name, *args)
|
61
|
-
schema.many(name, *args)
|
62
|
-
end
|
43
|
+
#
|
44
|
+
# To define the schema for an embedded document, call schema.key or schema.many from the class definition.
|
45
|
+
module EmbeddedDocument
|
46
|
+
def self.included (base)
|
47
|
+
base.send :include, ActiveRecordStub
|
48
|
+
base.send :include, ActiveRecord::Validations
|
49
|
+
base.send :include, AttributeMethods
|
50
|
+
|
51
|
+
base.write_inheritable_attribute(:schema, Schema.new(base, nil))
|
52
|
+
base.class_inheritable_reader :schema
|
63
53
|
end
|
64
54
|
|
65
55
|
# The parent object of the document.
|
@@ -2,18 +2,21 @@ module JsonRecord
|
|
2
2
|
# Adds the serialized JSON behavior to ActiveRecord.
|
3
3
|
module Serialized
|
4
4
|
def self.included (base)
|
5
|
-
base.
|
6
|
-
base.extend(ClassMethods)
|
5
|
+
base.extend(ActsMethods)
|
7
6
|
end
|
8
7
|
|
9
|
-
module
|
8
|
+
module ActsMethods
|
10
9
|
# Specify a field name that contains serialized JSON. The block will be yielded to with a
|
11
10
|
# Schema object that can then be used to define the fields in the JSON document. A class
|
12
11
|
# can have multiple fields that store JSON documents if necessary.
|
13
12
|
def serialize_to_json (field_name, &block)
|
13
|
+
unless include?(InstanceMethods)
|
14
|
+
class_inheritable_accessor :json_serialized_fields
|
15
|
+
extend ClassMethods
|
16
|
+
include InstanceMethods
|
17
|
+
end
|
14
18
|
field_name = field_name.to_s
|
15
19
|
self.json_serialized_fields ||= {}
|
16
|
-
include InstanceMethods unless include?(InstanceMethods)
|
17
20
|
schema = Schema.new(self, field_name)
|
18
21
|
field_schemas = json_serialized_fields[field_name]
|
19
22
|
if field_schemas
|
@@ -25,7 +28,9 @@ module JsonRecord
|
|
25
28
|
field_schemas << schema
|
26
29
|
block.call(schema) if block
|
27
30
|
end
|
28
|
-
|
31
|
+
end
|
32
|
+
|
33
|
+
module ClassMethods
|
29
34
|
# Get the field definition of the JSON field from the schema it is defined in.
|
30
35
|
def json_field_definition (name)
|
31
36
|
field = nil
|
data/lib/json_record.rb
CHANGED
@@ -18,3 +18,5 @@ require File.expand_path(File.join(File.dirname(__FILE__), 'json_record', 'embed
|
|
18
18
|
require File.expand_path(File.join(File.dirname(__FILE__), 'json_record', 'field_definition'))
|
19
19
|
require File.expand_path(File.join(File.dirname(__FILE__), 'json_record', 'json_field'))
|
20
20
|
require File.expand_path(File.join(File.dirname(__FILE__), 'json_record', 'serialized'))
|
21
|
+
|
22
|
+
ActiveRecord::Base.send(:include, JsonRecord::Serialized)
|
data/spec/serialized_spec.rb
CHANGED
@@ -151,7 +151,8 @@ describe JsonRecord::Serialized do
|
|
151
151
|
"map"=>{},
|
152
152
|
"verified"=>nil,
|
153
153
|
"when"=>nil,
|
154
|
-
"primary_trait"=>nil
|
154
|
+
"primary_trait"=>nil,
|
155
|
+
"dimension"=>nil
|
155
156
|
}
|
156
157
|
JsonRecord::Test::Model.new.attributes["traits"].should be_a(JsonRecord::EmbeddedDocumentArray)
|
157
158
|
end
|
data/spec/test_models.rb
CHANGED
@@ -27,15 +27,21 @@ module JsonRecord
|
|
27
27
|
Dir.delete(db_dir) if File.exist?(db_dir) and Dir.entries(db_dir).reject{|f| f.match(/^\.+$/)}.empty?
|
28
28
|
end
|
29
29
|
|
30
|
-
class Trait
|
31
|
-
|
32
|
-
key :
|
33
|
-
key :
|
34
|
-
|
30
|
+
class Trait
|
31
|
+
include JsonRecord::EmbeddedDocument
|
32
|
+
schema.key :name, :required => true
|
33
|
+
schema.key :value
|
34
|
+
schema.key :count, Integer
|
35
|
+
schema.many :sub_traits, Trait, :unique => [:name, :value]
|
36
|
+
end
|
37
|
+
|
38
|
+
class Dimension
|
39
|
+
include JsonRecord::EmbeddedDocument
|
40
|
+
schema.key :height, Integer, :required => true
|
41
|
+
schema.key :width, Integer, :required => true
|
35
42
|
end
|
36
43
|
|
37
44
|
class Model < ActiveRecord::Base
|
38
|
-
include JsonRecord::Serialized
|
39
45
|
serialize_to_json(:json) do |schema|
|
40
46
|
schema.key :name, String, :required => true, :length => 15
|
41
47
|
schema.key :value, Integer, :default => 0
|
@@ -48,6 +54,7 @@ module JsonRecord
|
|
48
54
|
schema.key :map, Hash
|
49
55
|
schema.key :primary_trait, Trait
|
50
56
|
schema.many :traits, Trait, :unique => :name
|
57
|
+
schema.key :dimension, Dimension
|
51
58
|
end
|
52
59
|
|
53
60
|
serialize_to_json(:compressed_json) do |schema|
|