ork 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +146 -18
- data/lib/ork/embedded.rb +48 -0
- data/lib/ork/errors.rb +8 -0
- data/lib/ork/model/associations.rb +114 -13
- data/lib/ork/model/class_methods.rb +106 -20
- data/lib/ork/model/document.rb +155 -0
- data/lib/ork/model/finders.rb +45 -13
- data/lib/ork/model/index.rb +20 -0
- data/lib/ork/model.rb +33 -114
- data/lib/ork/utils.rb +3 -2
- data/lib/ork.rb +3 -1
- data/ork.gemspec +2 -2
- data/rakefile +3 -26
- data/test/helper.rb +21 -31
- metadata +7 -13
- data/test/finders.rb +0 -43
- data/test/model.rb +0 -139
- data/test/reference.rb +0 -73
- data/test/test_riak_server.toml +0 -15
- data/test/test_riak_server.toml.example +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 609ee14359a522c9a80be687981cf6280fb2f2ea
|
4
|
+
data.tar.gz: d2b93d067769324259a9d48daebaff978a6e32c6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: beb105369966731ad130fb658f7586defa8d8d2c64f12e1438a3c6fad6946e75cf181a836d4c197f308020d1178733559ff76494f85e812691bfd35c096c71fe
|
7
|
+
data.tar.gz: caa7d2aff4293bc60f84cc9b85b228389447aa76ecac6ac291b85ff0ac23d059d2ec552eb4f7b00025fb4402d2b3db82a2eee27a67b26402c6f6c37fe9b219e6
|
data/README.md
CHANGED
@@ -1,45 +1,173 @@
|
|
1
|
-
#
|
1
|
+
# Ork
|
2
2
|
[![Gem Version](https://badge.fury.io/rb/ork.png)](http://badge.fury.io/rb/ork)
|
3
|
-
[![Build Status](https://secure.travis-ci.org/
|
4
|
-
[![Code Climate](https://codeclimate.com/github/
|
5
|
-
[![Coverage Status](https://coveralls.io/repos/
|
6
|
-
[![Dependency Status](https://gemnasium.com/
|
3
|
+
[![Build Status](https://secure.travis-ci.org/emancu/ork.png)](http://travis-ci.org/emancu/ork)
|
4
|
+
[![Code Climate](https://codeclimate.com/github/emancu/ork.png)](https://codeclimate.com/github/emancu/ork)
|
5
|
+
[![Coverage Status](https://coveralls.io/repos/emancu/ork/badge.png)](https://coveralls.io/r/emancu/ork)
|
6
|
+
[![Dependency Status](https://gemnasium.com/emancu/ork.png)](https://gemnasium.com/emancu/ork)
|
7
7
|
|
8
|
-
|
8
|
+
Ork is a small Ruby modeling layer for **Riak** database, inspired by [Ohm](http://ohm.keyvalue.org).
|
9
9
|
|
10
10
|
## Dependencies
|
11
11
|
|
12
12
|
`ork` requires Ruby 1.9 or later and the `riak-client` gem to connect to **Riak**.
|
13
13
|
|
14
|
+
Install dependencies using `dep` is easy as run:
|
15
|
+
|
16
|
+
dep install
|
17
|
+
|
18
|
+
## Installation
|
19
|
+
|
20
|
+
Install [Riak](http://basho.com/riak/) with your package manager:
|
21
|
+
|
22
|
+
$ brew install riak
|
23
|
+
|
24
|
+
Or download it from [Riak's download page](http://docs.basho.com/riak/latest/downloads/)
|
25
|
+
|
26
|
+
Once you have it installed, you can execute `riak start` and it will run on `localhost:8098` by default.
|
27
|
+
|
28
|
+
If you don't have Ork, try this:
|
29
|
+
|
30
|
+
$ gem install ork
|
31
|
+
|
14
32
|
## Getting started
|
15
33
|
|
16
|
-
|
34
|
+
Ork helps you to focus your energy on modeling and designing the object collaborations without worry about how Riak works.
|
35
|
+
Take a look at the example below:
|
36
|
+
|
37
|
+
### Example
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
class Post
|
41
|
+
include Ork::Document
|
42
|
+
|
43
|
+
attribute :name
|
44
|
+
attribute :age, default: 18
|
45
|
+
|
46
|
+
index :age
|
47
|
+
unique :name
|
48
|
+
end
|
49
|
+
|
50
|
+
class Comment
|
51
|
+
include Ork::Document
|
52
|
+
|
53
|
+
attribute :text
|
54
|
+
reference :post, :Post
|
55
|
+
end
|
56
|
+
```
|
57
|
+
|
58
|
+
It also gives you some helpful **class methods**:
|
59
|
+
|
60
|
+
|
61
|
+
| Class Method | Description | Example (ruby) |
|
62
|
+
|:-------------|:-------------------------------------------------|:-------------------------|
|
63
|
+
| bucket | `Riak::Bucket` The bucket assigned to this class | `#<Riak::Bucket {post}>` |
|
64
|
+
| bucket_name | `String` The bucket name | `"post"` |
|
65
|
+
| attributes | `Array` Attributes declared | `[:name, :age]` |
|
66
|
+
| indices | `Array` Indices declared | `[:age]` |
|
67
|
+
| uniques | `Array` Unique indices declared | `[:name]` |
|
68
|
+
| embedding | `Array` Embedded attributes declared | `[:post]` |
|
69
|
+
| defaults | `Hash` Defaults for attributes | `{:age=>18}` |
|
70
|
+
|
71
|
+
|
72
|
+
And for **instance methods** it defines:
|
73
|
+
|
74
|
+
| Instance Method | Description |
|
75
|
+
|:-----------------------------------|:--------------------------------------------------|
|
76
|
+
| new? | `Bool` Answer if its a new instance or not. |
|
77
|
+
| embeddable? | `Bool` Answer if its an embeddable object or not. |
|
78
|
+
| update(_attr_) | `Bool` Update model attributes and save it. |
|
79
|
+
| update_attributes(_attr_) | `Array` Update model attributes. |
|
80
|
+
| update_embedded_attributes(_attr_) | `Array` Update embedded model attributes. |
|
81
|
+
| reload | `<class>` Preload all the attributes from Riak. |
|
82
|
+
| save | `Bool` Persist document. |
|
83
|
+
| delete | `Bool` Delete the document from Riak. |
|
17
84
|
|
18
|
-
Ork::Model provides one attribute type:
|
19
85
|
|
20
|
-
- Ork::Model.attribute attribute
|
21
86
|
|
22
|
-
|
87
|
+
# Modeling
|
88
|
+
> Embeddable objects are those with `include Ork::Embeddable` and they can not be saved
|
89
|
+
> without a parent.
|
23
90
|
|
24
|
-
- Ork::Model.reference reference
|
25
|
-
- Ork::Model.referenced referenced
|
26
|
-
- Ork::Model.collection collection
|
27
91
|
|
28
|
-
|
92
|
+
Core behaviour of `Ork::Model`.
|
29
93
|
|
30
|
-
|
94
|
+
## attribute
|
31
95
|
|
32
|
-
|
96
|
+
An `attribute` is just any value that can be stored. It is composed of a `:name` and an optional `hash`.
|
97
|
+
|
98
|
+
```ruby
|
99
|
+
attribute :age, default: 18
|
100
|
+
```
|
101
|
+
|
102
|
+
#### Options
|
103
|
+
|
104
|
+
- `default: nil` set to the attribute a _value_ by default.
|
105
|
+
|
106
|
+
- `accessors: [:reader, :writer]` defines which accessors will be defined
|
107
|
+
* `:reader` a.k.a **attr_reader**, create a method to read the value.
|
108
|
+
* `:writer` a.k.a **attr_writer**, create a method to write the value.
|
109
|
+
* `:question` create a question method. Perfect for **bool** attributes.
|
110
|
+
|
111
|
+
|
112
|
+
## reference
|
33
113
|
|
34
114
|
It's a special kind of attribute that references another model.
|
35
115
|
Internally, Ork will keep a pointer to the model (its ID), but you get
|
36
116
|
accessors that give you real instances. You can think of it as the model
|
37
117
|
containing the foreign key to another model.
|
38
118
|
|
39
|
-
|
119
|
+
```ruby
|
120
|
+
reference :user, :User
|
121
|
+
```
|
122
|
+
|
123
|
+
## referenced
|
40
124
|
|
41
125
|
Provides an accessor to search for _one_ model that `reference` the current model.
|
42
126
|
|
43
|
-
|
127
|
+
```ruby
|
128
|
+
referenced :comment, :Comment
|
129
|
+
```
|
130
|
+
|
131
|
+
## collection
|
44
132
|
|
45
133
|
Provides an accessor to search for _all_ models that `reference` the current model.
|
134
|
+
|
135
|
+
```ruby
|
136
|
+
collection :comments, :Comment
|
137
|
+
```
|
138
|
+
|
139
|
+
## embed
|
140
|
+
> Only accepts embeddable objects.
|
141
|
+
|
142
|
+
It's a special kind of attribute that embeds another model.
|
143
|
+
Internally, Ork will keep the object as an attribute, but you get
|
144
|
+
accessors that give you real instances.
|
145
|
+
|
146
|
+
```ruby
|
147
|
+
embed :comment, :Comment
|
148
|
+
```
|
149
|
+
|
150
|
+
## embed_collection
|
151
|
+
> Only accepts embeddable objects.
|
152
|
+
|
153
|
+
Provides an accessor for _all_ models that are `embedded` into the current model.
|
154
|
+
It also provides a method for _adding_ objects to this collection.
|
155
|
+
|
156
|
+
```ruby
|
157
|
+
embed_collection :comments, :Comment
|
158
|
+
|
159
|
+
# It provides
|
160
|
+
def add_comments(a_comment)
|
161
|
+
# code
|
162
|
+
end
|
163
|
+
```
|
164
|
+
|
165
|
+
|
166
|
+
## embedded
|
167
|
+
> Only for embeddable objects.
|
168
|
+
|
169
|
+
Provides an accessor to the object that `embeds` the current model.
|
170
|
+
|
171
|
+
```ruby
|
172
|
+
embedded :post, :Post
|
173
|
+
```
|
data/lib/ork/embedded.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require_relative 'model'
|
2
|
+
|
3
|
+
module Ork
|
4
|
+
module Embeddable
|
5
|
+
|
6
|
+
def self.included(klass)
|
7
|
+
klass.send(:include, Ork::Model)
|
8
|
+
klass.extend(Ork::Model::Embedded::ClassMethods)
|
9
|
+
end
|
10
|
+
|
11
|
+
def embeddable?
|
12
|
+
true
|
13
|
+
end
|
14
|
+
|
15
|
+
def __parent
|
16
|
+
@attributes[model.__parent_key] or raise Ork::ParentMissing
|
17
|
+
end
|
18
|
+
|
19
|
+
def __parent=(object)
|
20
|
+
@attributes[model.__parent_key] = object
|
21
|
+
end
|
22
|
+
|
23
|
+
# Check for equality by doing the following assertions:
|
24
|
+
#
|
25
|
+
# 1. That the passed model is of the same type.
|
26
|
+
# 2. That they have the same attributes.
|
27
|
+
#
|
28
|
+
# How it was developed, 2 implies 1.
|
29
|
+
#
|
30
|
+
def ==(other)
|
31
|
+
other.kind_of?(model) &&
|
32
|
+
__persist_attributes == other.__persist_attributes &&
|
33
|
+
other.attributes[model.__parent_key] == @attributes[model.__parent_key]
|
34
|
+
end
|
35
|
+
alias :eql? :==
|
36
|
+
|
37
|
+
# Pretty print for the model
|
38
|
+
#
|
39
|
+
# Example:
|
40
|
+
#
|
41
|
+
# User.new(name: 'John').inspect
|
42
|
+
# # => #<User {:name=>"John"}>
|
43
|
+
#
|
44
|
+
def inspect
|
45
|
+
"#<#{model} #{attributes.inspect}>"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/ork/errors.rb
ADDED
@@ -6,7 +6,7 @@ module Ork::Model
|
|
6
6
|
# Example:
|
7
7
|
#
|
8
8
|
# class Post
|
9
|
-
# include Ork::
|
9
|
+
# include Ork::Document
|
10
10
|
#
|
11
11
|
# reference :user, :User
|
12
12
|
# end
|
@@ -14,7 +14,7 @@ module Ork::Model
|
|
14
14
|
# # It's the same as:
|
15
15
|
#
|
16
16
|
# class Post
|
17
|
-
# include Ork::
|
17
|
+
# include Ork::Document
|
18
18
|
#
|
19
19
|
# attribute :user_id
|
20
20
|
# index :user_id
|
@@ -50,8 +50,8 @@ module Ork::Model
|
|
50
50
|
end
|
51
51
|
|
52
52
|
define_method(:"#{name}=") do |value|
|
53
|
-
@_memo.delete(name)
|
54
53
|
send(writer, value ? value.id : nil)
|
54
|
+
@_memo[name] = value
|
55
55
|
end
|
56
56
|
|
57
57
|
define_method(name) do
|
@@ -66,13 +66,13 @@ module Ork::Model
|
|
66
66
|
#
|
67
67
|
# Example:
|
68
68
|
# class Post
|
69
|
-
# include Ork::
|
69
|
+
# include Ork::Document
|
70
70
|
#
|
71
71
|
# reference :user, :User
|
72
72
|
# end
|
73
73
|
#
|
74
74
|
# class User
|
75
|
-
# include Ork::
|
75
|
+
# include Ork::Document
|
76
76
|
#
|
77
77
|
# referenced :post, :Post
|
78
78
|
# end
|
@@ -80,7 +80,7 @@ module Ork::Model
|
|
80
80
|
# # is the same as
|
81
81
|
#
|
82
82
|
# class User
|
83
|
-
# include Ork::
|
83
|
+
# include Ork::Document
|
84
84
|
#
|
85
85
|
# def post
|
86
86
|
# Post.find(:user_id => self.id)
|
@@ -89,8 +89,11 @@ module Ork::Model
|
|
89
89
|
#
|
90
90
|
def referenced(name, model, reference = to_reference)
|
91
91
|
define_method name do
|
92
|
-
|
93
|
-
|
92
|
+
return nil if self.id.nil?
|
93
|
+
@_memo[name] ||= begin
|
94
|
+
model = Ork::Utils.const(self.class, model)
|
95
|
+
model.find(:"#{reference}_id", self.id).first
|
96
|
+
end
|
94
97
|
end
|
95
98
|
end
|
96
99
|
|
@@ -98,13 +101,13 @@ module Ork::Model
|
|
98
101
|
#
|
99
102
|
# Example:
|
100
103
|
# class Post
|
101
|
-
# include Ork::
|
104
|
+
# include Ork::Document
|
102
105
|
#
|
103
106
|
# reference :user, :User
|
104
107
|
# end
|
105
108
|
#
|
106
109
|
# class User
|
107
|
-
# include Ork::
|
110
|
+
# include Ork::Document
|
108
111
|
#
|
109
112
|
# collection :posts, :Post
|
110
113
|
# end
|
@@ -112,7 +115,7 @@ module Ork::Model
|
|
112
115
|
# # is the same as
|
113
116
|
#
|
114
117
|
# class User
|
115
|
-
# include Ork::
|
118
|
+
# include Ork::Document
|
116
119
|
#
|
117
120
|
# def posts
|
118
121
|
# Post.find(:user_id => self.id)
|
@@ -121,8 +124,106 @@ module Ork::Model
|
|
121
124
|
#
|
122
125
|
def collection(name, model, reference = to_reference)
|
123
126
|
define_method name do
|
124
|
-
|
125
|
-
|
127
|
+
return [] if self.id.nil?
|
128
|
+
@_memo[name] ||= begin
|
129
|
+
model = Ork::Utils.const(self.class, model)
|
130
|
+
model.find(:"#{reference}_id", self.id)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
# A macro for defining an attribute, and the accessors
|
136
|
+
# for a given model.
|
137
|
+
#
|
138
|
+
# Example:
|
139
|
+
#
|
140
|
+
# class Post
|
141
|
+
# include Ork::Document
|
142
|
+
#
|
143
|
+
# embed :author, :Author
|
144
|
+
# end
|
145
|
+
#
|
146
|
+
# # It's the same as:
|
147
|
+
#
|
148
|
+
# class Post
|
149
|
+
# include Ork::Document
|
150
|
+
#
|
151
|
+
# def author
|
152
|
+
# @embedding[:author]
|
153
|
+
# end
|
154
|
+
#
|
155
|
+
# def author=(author)
|
156
|
+
# @embedding[:author] = author
|
157
|
+
# author.__parent = self
|
158
|
+
# end
|
159
|
+
# end
|
160
|
+
#
|
161
|
+
def embed(name, model)
|
162
|
+
embedding << name unless embedding.include?(name)
|
163
|
+
|
164
|
+
define_method(name) do
|
165
|
+
return nil unless @embedding.has_key? name
|
166
|
+
@_memo[name] ||= begin
|
167
|
+
model = Ork::Utils.const(self.class, model)
|
168
|
+
model.new(@embedding[name])
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
define_method(:"#{name}=") do |object|
|
173
|
+
unless object.respond_to?(:embeddable?) && object.embeddable?
|
174
|
+
raise Ork::NotAnEmbeddableObject.new(object)
|
175
|
+
end
|
176
|
+
|
177
|
+
@embedding[name] = object.attributes
|
178
|
+
object.__parent = self
|
179
|
+
|
180
|
+
@_memo[name] = object
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
# A macro for find embedded objects of the same type, massive assign and
|
185
|
+
# syntactic sugar for add an object to the collection.
|
186
|
+
#
|
187
|
+
# Example:
|
188
|
+
#
|
189
|
+
# class Post
|
190
|
+
# include Ork::Document
|
191
|
+
#
|
192
|
+
# embed_collection :authors, :Author
|
193
|
+
# end
|
194
|
+
#
|
195
|
+
# # It's the same as:
|
196
|
+
#
|
197
|
+
# class Post
|
198
|
+
# include Ork::Document
|
199
|
+
#
|
200
|
+
# def authors
|
201
|
+
# # An array of authors
|
202
|
+
# end
|
203
|
+
#
|
204
|
+
# def add_author(author)
|
205
|
+
# # Add an author to the embed collection
|
206
|
+
# end
|
207
|
+
# end
|
208
|
+
#
|
209
|
+
def embed_collection(name, model)
|
210
|
+
embedding << name unless embedding.include?(name)
|
211
|
+
|
212
|
+
define_method(name) do
|
213
|
+
return [] unless @embedding.has_key? name
|
214
|
+
|
215
|
+
@_memo[name] ||= begin
|
216
|
+
model = Ork::Utils.const(self.class, model)
|
217
|
+
@embedding[name].map{|atts| model.new atts}
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
define_method(:"add_#{name}") do |object|
|
222
|
+
raise Ork::NotAnEmbeddableObject.new(object) unless object.embeddable?
|
223
|
+
|
224
|
+
object.__parent = self
|
225
|
+
@_memo[name] << object unless @_memo[name].nil?
|
226
|
+
@embedding[name] = Array(@embedding[name]) << object.attributes
|
126
227
|
end
|
127
228
|
end
|
128
229
|
|
@@ -1,8 +1,11 @@
|
|
1
|
+
require_relative 'index'
|
2
|
+
|
1
3
|
module Ork::Model
|
2
4
|
module ClassMethods
|
3
5
|
attr_writer :bucket_name
|
4
6
|
|
5
7
|
# Syntactic sugar for Model.new(atts).save
|
8
|
+
#
|
6
9
|
def create(atts = {})
|
7
10
|
new(atts).save
|
8
11
|
end
|
@@ -19,14 +22,22 @@ module Ork::Model
|
|
19
22
|
@bucket_name ||= self.to_s.downcase
|
20
23
|
end
|
21
24
|
|
25
|
+
def embedding
|
26
|
+
@embedding ||= []
|
27
|
+
end
|
28
|
+
|
22
29
|
def indices
|
23
|
-
@indices ||=
|
30
|
+
@indices ||= {}
|
24
31
|
end
|
25
32
|
|
26
33
|
def uniques
|
27
34
|
@uniques ||= []
|
28
35
|
end
|
29
36
|
|
37
|
+
def defaults
|
38
|
+
@defaults ||= {}
|
39
|
+
end
|
40
|
+
|
30
41
|
protected
|
31
42
|
|
32
43
|
# Declares persisted attributes.
|
@@ -34,7 +45,7 @@ module Ork::Model
|
|
34
45
|
#
|
35
46
|
# Example:
|
36
47
|
# class User
|
37
|
-
# include Ork::
|
48
|
+
# include Ork::Document
|
38
49
|
#
|
39
50
|
# attribute :name
|
40
51
|
# end
|
@@ -42,7 +53,7 @@ module Ork::Model
|
|
42
53
|
# # It's the same as:
|
43
54
|
#
|
44
55
|
# class User
|
45
|
-
# include Ork::
|
56
|
+
# include Ork::Document
|
46
57
|
#
|
47
58
|
# def name
|
48
59
|
# @attributes[:name]
|
@@ -53,37 +64,112 @@ module Ork::Model
|
|
53
64
|
# end
|
54
65
|
# end
|
55
66
|
#
|
56
|
-
def attribute(name,
|
67
|
+
def attribute(name, options = {})
|
57
68
|
attributes << name unless attributes.include?(name)
|
69
|
+
defaults[name] = options[:default] if options.has_key?(:default)
|
58
70
|
|
59
|
-
if
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
else
|
64
|
-
define_method(name) do
|
65
|
-
@attributes[name]
|
66
|
-
end
|
71
|
+
if options.has_key?(:accessors)
|
72
|
+
to_define = Array(options[:accessors]) & accessor_options
|
73
|
+
else # Default methods
|
74
|
+
to_define = [:reader, :writer]
|
67
75
|
end
|
68
76
|
|
69
|
-
|
70
|
-
@attributes[name] = value
|
71
|
-
end
|
77
|
+
to_define.each{|m| send("#{m}_for", name) }
|
72
78
|
end
|
73
79
|
|
74
|
-
# Index any
|
75
|
-
# use it in `find` statements.
|
76
|
-
|
77
|
-
|
80
|
+
# Index any attribute on your model. Once you index an attribute,
|
81
|
+
# you can use it in `find` statements.
|
82
|
+
#
|
83
|
+
def index(name)
|
84
|
+
indices[name] = Index.new(name) unless indices.include?(name)
|
78
85
|
end
|
79
86
|
|
80
|
-
# Create a unique index for any method on your model.
|
87
|
+
# Create a 'unique index' for any method on your model.
|
88
|
+
# Actually it creates a regular index, but it checks if
|
89
|
+
# it's repeated just before persist the new values.
|
81
90
|
#
|
82
91
|
# Note: if there is a conflict while saving, an
|
83
92
|
# `Ork::UniqueIndexViolation` violation is raised.
|
84
93
|
#
|
85
94
|
def unique(attribute)
|
86
95
|
uniques << attribute unless uniques.include?(attribute)
|
96
|
+
index(attribute)
|
97
|
+
end
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
# Valid options for attribute accessor value
|
102
|
+
#
|
103
|
+
def accessor_options
|
104
|
+
[:reader, :writer, :question]
|
105
|
+
end
|
106
|
+
|
107
|
+
# Create reader method
|
108
|
+
#
|
109
|
+
def reader_for(name)
|
110
|
+
define_method(name) do
|
111
|
+
@attributes[name]
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# Create writer method
|
116
|
+
#
|
117
|
+
def writer_for(name)
|
118
|
+
define_method(:"#{name}=") do |value|
|
119
|
+
@attributes[name] = value
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# Create question method
|
124
|
+
#
|
125
|
+
def question_for(name)
|
126
|
+
define_method(:"#{name}?") do
|
127
|
+
!!@attributes[name]
|
128
|
+
end
|
87
129
|
end
|
88
130
|
end
|
131
|
+
|
132
|
+
module Embedded
|
133
|
+
module ClassMethods
|
134
|
+
attr_accessor :__parent_key
|
135
|
+
|
136
|
+
# Declares parent accessors for embedded objects and set the parent key
|
137
|
+
#
|
138
|
+
# Example:
|
139
|
+
# class Comment
|
140
|
+
# include Ork::Embeddable
|
141
|
+
#
|
142
|
+
# embedded :post, :Post
|
143
|
+
# end
|
144
|
+
#
|
145
|
+
# # It's the same as:
|
146
|
+
#
|
147
|
+
# class Comment
|
148
|
+
# include Ork::Embeddable
|
149
|
+
#
|
150
|
+
# def post
|
151
|
+
# @attributes[:post]
|
152
|
+
# end
|
153
|
+
#
|
154
|
+
# def post=(post)
|
155
|
+
# @attributes[:post] = post
|
156
|
+
# end
|
157
|
+
# end
|
158
|
+
#
|
159
|
+
def embedded(name, model)
|
160
|
+
@__parent_key = name
|
161
|
+
|
162
|
+
define_method(name) do
|
163
|
+
@attributes[name]
|
164
|
+
end
|
165
|
+
|
166
|
+
define_method(:"#{name}=") do |object|
|
167
|
+
raise Ork::ParentMissing if object.nil?
|
168
|
+
|
169
|
+
@attributes[name] = object
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
89
175
|
end
|