openlogic-couchrest_model 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +11 -0
- data/.rspec +4 -0
- data/Gemfile +4 -0
- data/LICENSE +176 -0
- data/README.md +137 -0
- data/Rakefile +38 -0
- data/THANKS.md +21 -0
- data/VERSION +1 -0
- data/benchmarks/dirty.rb +118 -0
- data/couchrest_model.gemspec +36 -0
- data/history.md +309 -0
- data/init.rb +1 -0
- data/lib/couchrest/model.rb +10 -0
- data/lib/couchrest/model/associations.rb +231 -0
- data/lib/couchrest/model/base.rb +129 -0
- data/lib/couchrest/model/callbacks.rb +28 -0
- data/lib/couchrest/model/casted_array.rb +83 -0
- data/lib/couchrest/model/casted_by.rb +33 -0
- data/lib/couchrest/model/casted_hash.rb +84 -0
- data/lib/couchrest/model/class_proxy.rb +135 -0
- data/lib/couchrest/model/collection.rb +273 -0
- data/lib/couchrest/model/configuration.rb +67 -0
- data/lib/couchrest/model/connection.rb +70 -0
- data/lib/couchrest/model/core_extensions/hash.rb +9 -0
- data/lib/couchrest/model/core_extensions/time_parsing.rb +66 -0
- data/lib/couchrest/model/design_doc.rb +128 -0
- data/lib/couchrest/model/designs.rb +91 -0
- data/lib/couchrest/model/designs/view.rb +513 -0
- data/lib/couchrest/model/dirty.rb +39 -0
- data/lib/couchrest/model/document_queries.rb +99 -0
- data/lib/couchrest/model/embeddable.rb +78 -0
- data/lib/couchrest/model/errors.rb +25 -0
- data/lib/couchrest/model/extended_attachments.rb +83 -0
- data/lib/couchrest/model/persistence.rb +178 -0
- data/lib/couchrest/model/properties.rb +228 -0
- data/lib/couchrest/model/property.rb +114 -0
- data/lib/couchrest/model/property_protection.rb +71 -0
- data/lib/couchrest/model/proxyable.rb +183 -0
- data/lib/couchrest/model/support/couchrest_database.rb +13 -0
- data/lib/couchrest/model/support/couchrest_design.rb +33 -0
- data/lib/couchrest/model/typecast.rb +154 -0
- data/lib/couchrest/model/validations.rb +80 -0
- data/lib/couchrest/model/validations/casted_model.rb +16 -0
- data/lib/couchrest/model/validations/locale/en.yml +5 -0
- data/lib/couchrest/model/validations/uniqueness.rb +69 -0
- data/lib/couchrest/model/views.rb +151 -0
- data/lib/couchrest/railtie.rb +24 -0
- data/lib/couchrest_model.rb +66 -0
- data/lib/rails/generators/couchrest_model.rb +16 -0
- data/lib/rails/generators/couchrest_model/config/config_generator.rb +18 -0
- data/lib/rails/generators/couchrest_model/config/templates/couchdb.yml +21 -0
- data/lib/rails/generators/couchrest_model/model/model_generator.rb +27 -0
- data/lib/rails/generators/couchrest_model/model/templates/model.rb +2 -0
- data/spec/.gitignore +1 -0
- data/spec/fixtures/attachments/README +3 -0
- data/spec/fixtures/attachments/couchdb.png +0 -0
- data/spec/fixtures/attachments/test.html +11 -0
- data/spec/fixtures/config/couchdb.yml +10 -0
- data/spec/fixtures/models/article.rb +36 -0
- data/spec/fixtures/models/base.rb +164 -0
- data/spec/fixtures/models/card.rb +19 -0
- data/spec/fixtures/models/cat.rb +23 -0
- data/spec/fixtures/models/client.rb +6 -0
- data/spec/fixtures/models/course.rb +27 -0
- data/spec/fixtures/models/event.rb +8 -0
- data/spec/fixtures/models/invoice.rb +14 -0
- data/spec/fixtures/models/key_chain.rb +5 -0
- data/spec/fixtures/models/membership.rb +4 -0
- data/spec/fixtures/models/person.rb +11 -0
- data/spec/fixtures/models/project.rb +6 -0
- data/spec/fixtures/models/question.rb +7 -0
- data/spec/fixtures/models/sale_entry.rb +9 -0
- data/spec/fixtures/models/sale_invoice.rb +14 -0
- data/spec/fixtures/models/service.rb +10 -0
- data/spec/fixtures/models/user.rb +22 -0
- data/spec/fixtures/views/lib.js +3 -0
- data/spec/fixtures/views/test_view/lib.js +3 -0
- data/spec/fixtures/views/test_view/only-map.js +4 -0
- data/spec/fixtures/views/test_view/test-map.js +3 -0
- data/spec/fixtures/views/test_view/test-reduce.js +3 -0
- data/spec/functional/validations_spec.rb +8 -0
- data/spec/spec_helper.rb +60 -0
- data/spec/unit/active_model_lint_spec.rb +30 -0
- data/spec/unit/assocations_spec.rb +242 -0
- data/spec/unit/attachment_spec.rb +176 -0
- data/spec/unit/base_spec.rb +537 -0
- data/spec/unit/casted_spec.rb +72 -0
- data/spec/unit/class_proxy_spec.rb +167 -0
- data/spec/unit/collection_spec.rb +86 -0
- data/spec/unit/configuration_spec.rb +77 -0
- data/spec/unit/connection_spec.rb +148 -0
- data/spec/unit/core_extensions/time_parsing.rb +77 -0
- data/spec/unit/design_doc_spec.rb +241 -0
- data/spec/unit/designs/view_spec.rb +831 -0
- data/spec/unit/designs_spec.rb +134 -0
- data/spec/unit/dirty_spec.rb +436 -0
- data/spec/unit/embeddable_spec.rb +498 -0
- data/spec/unit/inherited_spec.rb +33 -0
- data/spec/unit/persistence_spec.rb +481 -0
- data/spec/unit/property_protection_spec.rb +192 -0
- data/spec/unit/property_spec.rb +481 -0
- data/spec/unit/proxyable_spec.rb +376 -0
- data/spec/unit/subclass_spec.rb +85 -0
- data/spec/unit/typecast_spec.rb +521 -0
- data/spec/unit/validations_spec.rb +140 -0
- data/spec/unit/view_spec.rb +367 -0
- metadata +301 -0
@@ -0,0 +1,36 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{openlogic-couchrest_model}
|
5
|
+
s.version = `cat VERSION`.strip
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["J. Chris Anderson", "Matt Aimonetti", "Marcos Tapajos", "Will Leinweber", "Sam Lown"]
|
9
|
+
s.date = File.mtime('VERSION')
|
10
|
+
s.description = %q{CouchRest Model provides aditional features to the standard CouchRest Document class such as properties, view designs, associations, callbacks, typecasting and validations.}
|
11
|
+
s.email = %q{jchris@apache.org}
|
12
|
+
s.extra_rdoc_files = [
|
13
|
+
"LICENSE",
|
14
|
+
"README.md",
|
15
|
+
"THANKS.md"
|
16
|
+
]
|
17
|
+
s.homepage = %q{http://github.com/couchrest/couchrest_model}
|
18
|
+
s.rubygems_version = %q{1.3.7}
|
19
|
+
s.summary = %q{Extends the CouchRest Document for advanced modelling.}
|
20
|
+
|
21
|
+
s.files = `git ls-files`.split("\n")
|
22
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
23
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
24
|
+
s.require_paths = ["lib"]
|
25
|
+
|
26
|
+
s.add_dependency(%q<couchrest>, "~> 1.1.2")
|
27
|
+
s.add_dependency(%q<mime-types>, "~> 1.15")
|
28
|
+
s.add_dependency(%q<activemodel>, "~> 3.0")
|
29
|
+
s.add_dependency(%q<tzinfo>, "~> 0.3.22")
|
30
|
+
s.add_development_dependency(%q<rspec>, "~> 2.6.0")
|
31
|
+
s.add_development_dependency(%q<json>, ["~> 1.5.1"])
|
32
|
+
s.add_development_dependency(%q<rack-test>, ">= 0.5.7")
|
33
|
+
s.add_development_dependency("rake", ">= 0.8.0")
|
34
|
+
# s.add_development_dependency("jruby-openssl", ">= 0.7.3")
|
35
|
+
end
|
36
|
+
|
data/history.md
ADDED
@@ -0,0 +1,309 @@
|
|
1
|
+
# CouchRest Model Change History
|
2
|
+
|
3
|
+
## 1.1.3
|
4
|
+
|
5
|
+
* CouchRest::Model::Base.respond_to_missing? and respond_to? (Kim Burgestrand)
|
6
|
+
|
7
|
+
## 1.1.2 - 2011-07-23
|
8
|
+
|
9
|
+
* Minor fixes
|
10
|
+
* Upgrade to couchrest 1.1.2
|
11
|
+
* Override as_couch_json to ensure nil values not stored
|
12
|
+
* Removing restriction that prohibited objects that cast as an array to be loaded.
|
13
|
+
|
14
|
+
## 1.1.1 - 2011-07-04
|
15
|
+
|
16
|
+
* Minor fix
|
17
|
+
* Bumping CouchRest version dependency for important initialize method fix.
|
18
|
+
* Ensuring super on Embeddable#initialize can be called.
|
19
|
+
|
20
|
+
## 1.1.0 - 2011-06-25
|
21
|
+
|
22
|
+
* Major Alterations
|
23
|
+
* CastedModel no longer requires a Hash. Automatically includes all required methods.
|
24
|
+
* CastedModel module renamed to Embeddable (old still works!)
|
25
|
+
|
26
|
+
* Minor Fixes
|
27
|
+
* Validation callbacks now support context (thanks kostia)
|
28
|
+
* Document comparisons now performed using database and document ID (pointer by neocsr)
|
29
|
+
* Automatic config generation now supported (thanks lucasrenan)
|
30
|
+
* Comparing documents resorts to Hash comparison if both IDs are nil. (pointer by kostia)
|
31
|
+
|
32
|
+
## 1.1.0.rc1 - 2011-06-08
|
33
|
+
|
34
|
+
* New Features
|
35
|
+
* Properties with a nil value are now no longer sent to the database.
|
36
|
+
* Now possible to build new objects via CastedArray#build
|
37
|
+
* Implement #get! and #find! class methods
|
38
|
+
* Now is possible delete particular elements in casted array(Kostiantyn Kahanskyi)
|
39
|
+
|
40
|
+
* Minor fixes
|
41
|
+
* #as_json now correctly uses ActiveSupports methods.
|
42
|
+
* Rails 3.1 support (Peter Williams)
|
43
|
+
* Initialization blocks when creating new models (Peter Williams)
|
44
|
+
* Removed railties dependency (DAddYE)
|
45
|
+
* DesignDoc cache refreshed if a database is deleted.
|
46
|
+
* Fixing dirty tracking on collection_of association.
|
47
|
+
* Uniqueness Validation views created on initialization, not on demand!
|
48
|
+
* #destroy freezes object instead of removing _id and _rev, better for callbacks (pointer by karmi)
|
49
|
+
* #destroyed? method now available
|
50
|
+
* #reload no longer uses Hash#merge! which was causing issues with dirty tracking on casted models. (pointer by kostia)
|
51
|
+
* Non-property mass assignment on #new no longer possible without :directly_set_attributes option.
|
52
|
+
* Using CouchRest 1.1.0.pre3. (No more Hashes!)
|
53
|
+
* Fixing problem assigning a CastedHash to a property declared as a Hash (Kostiantyn Kahanskyi, gfmtim)
|
54
|
+
|
55
|
+
## 1.1.0.beta5 - 2011-04-30
|
56
|
+
|
57
|
+
* Major changes:
|
58
|
+
* Database auto configuration, with connection options!
|
59
|
+
* Changed default CouchRest Model type to 'type' to be more consistent with ActiveRecord's reserverd words we're all used to (sorry for the change again!!)
|
60
|
+
|
61
|
+
* Minor changes
|
62
|
+
* Added filter option to designs (Used with CouchDB _changes feeds)
|
63
|
+
|
64
|
+
## 1.1.0.beta4
|
65
|
+
|
66
|
+
* Major changes:
|
67
|
+
* Fast Dirty Tracking! Many thanks to @sobakasu (Andrew Williams)
|
68
|
+
* Default CouchRest Model type field now set to 'model' instead of 'couchrest-type'.
|
69
|
+
|
70
|
+
* Minor enhancements:
|
71
|
+
* Adding "couchrest-hash" to Design Docs with aim to improve view update handling.
|
72
|
+
* Major changes to the way design document updates are handled internally.
|
73
|
+
* Added "auto_update_design_doc" configuration option.
|
74
|
+
* Using #descending on View object will automatically swap startkey with endkey.
|
75
|
+
|
76
|
+
## 1.1.0.beta3
|
77
|
+
|
78
|
+
* Removed
|
79
|
+
|
80
|
+
## 1.1.0.beta2
|
81
|
+
|
82
|
+
* Minor enhancements:
|
83
|
+
* Time handling improved in accordance with CouchRest 1.1.0. Always set to UTC.
|
84
|
+
* Refinements to associations and uniqueness validation for proxy (based on issue found by Gleb Kanterov)
|
85
|
+
* Added :allow_nil and :allow_blank options when creating a new view
|
86
|
+
* Unique Validation now supports scopes!
|
87
|
+
* Added support for #keys with list on Design View.
|
88
|
+
|
89
|
+
## 1.1.0.beta
|
90
|
+
|
91
|
+
* Epic enhancements:
|
92
|
+
* Added "View" object for dynamic view queries
|
93
|
+
* Added easy to use proxy_for and proxied_by class methods for proxying data
|
94
|
+
|
95
|
+
* Minor enhancements:
|
96
|
+
* A yield parameter in an anonymous casted model property block is no longer required (@samlown)
|
97
|
+
* Narrow the rescued exception to avoid catching class evaluation errors that has nothing to to with the association (thanks Simone Carletti)
|
98
|
+
* Fix validate uniqueness test that was never executed (thanks Simone Carletti)
|
99
|
+
* Adds a #reload method to reload document attributes (thanks Simone Carletti)
|
100
|
+
* Numeric types can be casted from strings with leading or trailing whitespace (thanks chrisdurtschi)
|
101
|
+
* CollectionProxy no longer provided by default with simple views (pending deprication)
|
102
|
+
|
103
|
+
## CouchRest Model 1.0.0
|
104
|
+
|
105
|
+
* Major enhancements
|
106
|
+
* Support for configuration module and "model_type_key" option for overriding model's type key
|
107
|
+
* Added "mass_assign_any_attribute" configuration option to allow setting anything via the attribute= method.
|
108
|
+
|
109
|
+
* Minor enhancements
|
110
|
+
* Fixing find("") issue (thanks epochwolf)
|
111
|
+
* Altered protected attributes so that hash provided to #attributes= is not modified
|
112
|
+
* Altering typecasting for floats to better handle commas and points
|
113
|
+
* Fixing the lame pagination bug where database url (and pass!!) were included in view requests (Thanks James Hayton)
|
114
|
+
|
115
|
+
Notes:
|
116
|
+
|
117
|
+
* 2010-10-22 @samlown:
|
118
|
+
* ActiveModel Attribute support was added but has now been removed due to major performance issues.
|
119
|
+
Until these have been resolved (if possible?!) they should not be included. See the
|
120
|
+
'active_model_attrs' if you'd like to test.
|
121
|
+
|
122
|
+
## CouchRest Model 1.0.0.beta8
|
123
|
+
|
124
|
+
* Major enhancements
|
125
|
+
* Added model generator
|
126
|
+
|
127
|
+
* Minor enhancements
|
128
|
+
* Raise error on adding objects to "collection_of" without an id
|
129
|
+
* Allow mixing of protected and accessible properties. Any unspecified properties are now assumed to be protected by default
|
130
|
+
* Parsing times without zone
|
131
|
+
* Using latest rspec (2.0.0.beta.19)
|
132
|
+
|
133
|
+
## CouchRest Model 1.0.0.beta7
|
134
|
+
|
135
|
+
* Major enhancements
|
136
|
+
* Renamed ExtendedDocument to CouchRest::Model
|
137
|
+
* Added initial support for simple belongs_to associations
|
138
|
+
* Added support for basic collection_of association (unique to document databases!)
|
139
|
+
* Moved Validation to ActiveModel
|
140
|
+
* Moved Callbacks to ActiveModel
|
141
|
+
* Removed support for properties defined using a string for the type instead of a class
|
142
|
+
* Validation always included
|
143
|
+
* Uniqueness validation now available
|
144
|
+
|
145
|
+
* Minor enhancements
|
146
|
+
* Removed support for auto_validate! and :length on properties
|
147
|
+
|
148
|
+
|
149
|
+
## 1.0.0.beta6
|
150
|
+
|
151
|
+
* Major enhancements
|
152
|
+
* Added support for anonymous CastedModels defined in Documents
|
153
|
+
|
154
|
+
* Minor enhancements
|
155
|
+
* Added 'find_by_*' alias for finding first item in view with matching key.
|
156
|
+
* Fixed issue with active_support in Rails3 and text in README for JSON.
|
157
|
+
* Refactoring of properties, added read_attribute and write_attribute methods.
|
158
|
+
* Now possible to send anything to update_attribtues method. Invalid or readonly attributes will be ignored.
|
159
|
+
* Attributes with arrays are *always* instantiated as a CastedArray.
|
160
|
+
* Setting a property of type Array (or keyed hash) must be an array or an error will be raised.
|
161
|
+
* Now possible to set Array attribute from hash where keys determine order.
|
162
|
+
|
163
|
+
## 1.0.0.beta5
|
164
|
+
|
165
|
+
* Minor enhancements
|
166
|
+
* Added 'find' alias for 'get' for easier rails transition
|
167
|
+
|
168
|
+
## 1.0.0.beta3
|
169
|
+
|
170
|
+
* Minor enhancements
|
171
|
+
* Removed Validation by default, requires too many structure changes (FAIL)
|
172
|
+
* Added support for instantiation of documents read from database as couchrest-type provided (Sam Lown)
|
173
|
+
* Improved attachment handling for detecting file type (Sam Lown)
|
174
|
+
* Removing some monkey patches and relying on active_support for constantize and humanize (Sam Lown)
|
175
|
+
* Added support for setting type directly on property (Sam Lown)
|
176
|
+
|
177
|
+
|
178
|
+
## 1.0.0.beta2
|
179
|
+
|
180
|
+
* Minor enhancements
|
181
|
+
* Enable Validation by default and refactored location (Sam Lown)
|
182
|
+
|
183
|
+
## 1.0.0.beta
|
184
|
+
|
185
|
+
* Major enhancements
|
186
|
+
* Separated ExtendedDocument from main CouchRest gem (Sam Lown)
|
187
|
+
|
188
|
+
* Minor enhancements
|
189
|
+
* active_support included by default
|
190
|
+
|
191
|
+
## 0.37
|
192
|
+
|
193
|
+
* Minor enhancements
|
194
|
+
* Added gemspec (needed for Bundler install) (Tapajós)
|
195
|
+
|
196
|
+
## 0.36
|
197
|
+
|
198
|
+
* Major enhancements
|
199
|
+
* Adds support for continuous replication (sauy7)
|
200
|
+
* Automatic Type Casting (Alexander Uvarov, Sam Lown, Tim Heighes, Will Leinweber)
|
201
|
+
* Added a search method to CouchRest:Database to search the documents in a given database. (Dave Farkas, Arnaud Berthomier, John Wood)
|
202
|
+
|
203
|
+
* Minor enhancements
|
204
|
+
* Provide a description of the timeout error (John Wood)
|
205
|
+
|
206
|
+
## 0.35
|
207
|
+
|
208
|
+
* Major enhancements
|
209
|
+
* CouchRest::ExtendedDocument allow chaining the inherit class callback (Kenneth Kalmer) - http://github.com/couchrest/couchrest/issues#issue/8
|
210
|
+
|
211
|
+
* Minor enhancements
|
212
|
+
* Fix attachment bug (Johannes Jörg Schmidt)
|
213
|
+
* Fix create database exception bug (Damien Mathieu)
|
214
|
+
* Compatible with restclient >= 1.4.0 new responses (Julien Kirch)
|
215
|
+
* Bug fix: Attribute protection no longer strips attributes coming from the database (Will Leinweber)
|
216
|
+
* Bug fix: Remove double CGI escape when PUTting an attachment (nzoschke)
|
217
|
+
* Bug fix: Changing Class proxy to set database on result sets (Peter Gumeson)
|
218
|
+
* Bug fix: Updated time regexp (Nolan Darilek)
|
219
|
+
* Added an update_doc method to database to handle conflicts during atomic updates. (Pierre Larochelle)
|
220
|
+
* Bug fix: http://github.com/couchrest/couchrest/issues/#issue/2 (Luke Burton)
|
221
|
+
|
222
|
+
## 0.34
|
223
|
+
|
224
|
+
* Major enhancements
|
225
|
+
|
226
|
+
* Added support for https database URIs. (Mathias Meyer)
|
227
|
+
* Changing some validations to be compatible with activemodel. (Marcos Tapajós)
|
228
|
+
* Adds attribute protection to properties. (Will Leinweber)
|
229
|
+
* Improved CouchRest::Database#save_doc, added "batch" mode to significantly speed up saves at cost of lower durability gurantees. (Igal Koshevoy)
|
230
|
+
* Added CouchRest::Database#bulk_save_doc and #batch_save_doc as human-friendlier wrappers around #save_doc. (Igal Koshevoy)
|
231
|
+
|
232
|
+
* Minor enhancements
|
233
|
+
|
234
|
+
* Fix content_type handling for attachments
|
235
|
+
* Fixed a bug in the pagination code that caused it to paginate over records outside of the scope of the view parameters.(John Wood)
|
236
|
+
* Removed amount_pages calculation for the pagination collection, since it cannot be reliably calculated without a view.(John Wood)
|
237
|
+
* Bug fix: http://github.com/couchrest/couchrest/issues/#issue/2 (Luke Burton)
|
238
|
+
* Bug fix: http://github.com/couchrest/couchrest/issues/#issue/1 (Marcos Tapajós)
|
239
|
+
* Removed the Database class deprecation notices (Matt Aimonetti)
|
240
|
+
* Adding support to :cast_as => 'Date'. (Marcos Tapajós)
|
241
|
+
* Improve documentation (Marcos Tapajós)
|
242
|
+
* Streamer fixes (Julien Sanchez)
|
243
|
+
* Fix Save on Document & ExtendedDocument crashed if bulk (Julien Sanchez)
|
244
|
+
* Fix Initialization of ExtendentDocument model shouldn't failed on a nil value in argument (deepj)
|
245
|
+
* Change to use Jeweler and Gemcutter (Marcos Tapajós)
|
246
|
+
|
247
|
+
## 0.33
|
248
|
+
|
249
|
+
* Major enhancements
|
250
|
+
|
251
|
+
* Added a new Rack logger middleware letting you log/save requests/queries (Matt Aimonetti)
|
252
|
+
|
253
|
+
* Minor enhancements
|
254
|
+
|
255
|
+
* Added #amount_pages to a paginated result array (Matt Aimonetti)
|
256
|
+
* Ruby 1.9.2 compatible (Matt Aimonetti)
|
257
|
+
* Added a property? method for property cast as :boolean (John Wood)
|
258
|
+
* Added an option to force the deletion of a attachments (bypass 409s) (Matt Aimonetti)
|
259
|
+
* Created a new abstraction layer for the REST API (Matt Aimonetti)
|
260
|
+
* Bug fix: made ExtendedDocument#all compatible with Couch 0.10 (tc)
|
261
|
+
|
262
|
+
## 0.32
|
263
|
+
|
264
|
+
* Major enhancements
|
265
|
+
|
266
|
+
* ExtendedDocument.get doesn't raise an exception anymore. If no documents are found nil is returned.
|
267
|
+
* ExtendedDocument.get! works the say #get used to work and will raise an exception if a document isn't found.
|
268
|
+
|
269
|
+
* Minor enhancements
|
270
|
+
|
271
|
+
* Bug fix: Model.all(:keys => [1,2]) was not working (Matt Aimonetti)
|
272
|
+
* Added ValidationErrors#count in order to play nicely with Rails (Peter Wagenet)
|
273
|
+
* Bug fix: class proxy design doc refresh (Daniel Kirsh)
|
274
|
+
* Bug fix: the count method on the proxy collection was missing (Daniel Kirsch)
|
275
|
+
* Added #amount_pages to a paginated collection. (Matt Aimonetti)
|
276
|
+
|
277
|
+
## 0.31
|
278
|
+
|
279
|
+
* Major enhancements
|
280
|
+
|
281
|
+
* Created an abstraction HTTP layer to support different http adapters (Matt Aimonetti)
|
282
|
+
* Added ExtendedDocument.create({}) and #create!({}) so you don't have to do Model.new.create (Matt Aimonetti)
|
283
|
+
|
284
|
+
* Minor enhancements
|
285
|
+
|
286
|
+
* Added an init.rb file for easy usage as a Rails plugin (Aaron Quint)
|
287
|
+
* Bug fix: pagination shouldn't die on empty results (Arnaud Berthomier)
|
288
|
+
* Optimized ExtendedDocument.count to run about 3x faster (Matt Aimonetti)
|
289
|
+
* Added Float casting (Ryan Felton & Matt Aimonetti)
|
290
|
+
|
291
|
+
## 0.30
|
292
|
+
|
293
|
+
* Major enhancements
|
294
|
+
|
295
|
+
* Added support for pagination (John Wood)
|
296
|
+
* Improved performance when initializing documents with timestamps (Matt Aimonetti)
|
297
|
+
|
298
|
+
* Minor enhancements
|
299
|
+
|
300
|
+
* Extended the API to retrieve an attachment URI (Matt Aimonetti)
|
301
|
+
* Bug fix: default value should be able to be set as false (Alexander Uvarov)
|
302
|
+
* Bug fix: validates_is_numeric should be able to properly validate a Float instance (Rob Kaufman)
|
303
|
+
* Bug fix: fixed the Timeout implementation (Seth Falcon)
|
304
|
+
|
305
|
+
|
306
|
+
---
|
307
|
+
|
308
|
+
Unfortunately, before 0.30 we did not keep a track of the modifications made to CouchRest.
|
309
|
+
You can see the full commit history on GitHub: http://github.com/couchrest/couchrest/commits/master/
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__),'lib', 'couchrest', 'model')
|
@@ -0,0 +1,231 @@
|
|
1
|
+
module CouchRest
|
2
|
+
module Model
|
3
|
+
module Associations
|
4
|
+
|
5
|
+
# Basic support for relationships between CouchRest::Model::Base
|
6
|
+
|
7
|
+
def self.included(base)
|
8
|
+
base.extend(ClassMethods)
|
9
|
+
end
|
10
|
+
|
11
|
+
module ClassMethods
|
12
|
+
|
13
|
+
# Define an association that this object belongs to.
|
14
|
+
#
|
15
|
+
# An attribute will be created matching the name of the attribute
|
16
|
+
# with '_id' on the end, or the foreign key (:foreign_key) provided.
|
17
|
+
#
|
18
|
+
# Searching for the assocated object is performed using a string
|
19
|
+
# (:proxy) to be evaulated in the context of the owner. Typically
|
20
|
+
# this will be set to the class name (:class_name), or determined
|
21
|
+
# automatically if the owner belongs to a proxy object.
|
22
|
+
#
|
23
|
+
# If the association owner is proxied by another model, than an attempt will
|
24
|
+
# be made to automatically determine the correct place to request
|
25
|
+
# the documents. Typically, this is a method with the pluralized name of the
|
26
|
+
# association inside owner's owner, or proxy.
|
27
|
+
#
|
28
|
+
# For example, imagine a company acts as a proxy for invoices and clients.
|
29
|
+
# If an invoice belongs to a client, the invoice will need to access the
|
30
|
+
# list of clients via the proxy. So a request to search for the associated
|
31
|
+
# client from an invoice would look like:
|
32
|
+
#
|
33
|
+
# self.company.clients
|
34
|
+
#
|
35
|
+
# If the name of the collection proxy is not the pluralized assocation name,
|
36
|
+
# it can be set with the :proxy_name option.
|
37
|
+
#
|
38
|
+
def belongs_to(attrib, *options)
|
39
|
+
opts = merge_belongs_to_association_options(attrib, options.first)
|
40
|
+
|
41
|
+
property(opts[:foreign_key], opts)
|
42
|
+
|
43
|
+
create_belongs_to_getter(attrib, opts)
|
44
|
+
create_belongs_to_setter(attrib, opts)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Provide access to a collection of objects where the associated
|
48
|
+
# property contains a list of the collection item ids.
|
49
|
+
#
|
50
|
+
# The following:
|
51
|
+
#
|
52
|
+
# collection_of :groups
|
53
|
+
#
|
54
|
+
# creates a pseudo property called "groups" which allows access
|
55
|
+
# to a CollectionOfProxy object. Adding, replacing or removing entries in this
|
56
|
+
# proxy will cause the matching property array, in this case "group_ids", to
|
57
|
+
# be kept in sync.
|
58
|
+
#
|
59
|
+
# Any manual changes made to the collection ids property (group_ids), unless replaced, will require
|
60
|
+
# a reload of the CollectionOfProxy for the two sets of data to be in sync:
|
61
|
+
#
|
62
|
+
# group_ids = ['123']
|
63
|
+
# groups == [Group.get('123')]
|
64
|
+
# group_ids << '321'
|
65
|
+
# groups == [Group.get('123')]
|
66
|
+
# groups(true) == [Group.get('123'), Group.get('321')]
|
67
|
+
#
|
68
|
+
# Of course, saving the parent record will store the collection ids as they are
|
69
|
+
# found.
|
70
|
+
#
|
71
|
+
# The CollectionOfProxy supports the following array functions, anything else will cause
|
72
|
+
# a mismatch between the collection objects and collection ids:
|
73
|
+
#
|
74
|
+
# groups << obj
|
75
|
+
# groups.push obj
|
76
|
+
# groups.unshift obj
|
77
|
+
# groups[0] = obj
|
78
|
+
# groups.pop == obj
|
79
|
+
# groups.shift == obj
|
80
|
+
#
|
81
|
+
# Addtional options match those of the the belongs_to method.
|
82
|
+
#
|
83
|
+
# NOTE: This method is *not* recommended for large collections or collections that change
|
84
|
+
# frequently! Use with prudence.
|
85
|
+
#
|
86
|
+
def collection_of(attrib, *options)
|
87
|
+
opts = merge_belongs_to_association_options(attrib, options.first)
|
88
|
+
opts[:foreign_key] = opts[:foreign_key].pluralize
|
89
|
+
opts[:readonly] = true
|
90
|
+
|
91
|
+
property(opts[:foreign_key], [], opts)
|
92
|
+
|
93
|
+
create_collection_of_property_setter(attrib, opts)
|
94
|
+
create_collection_of_getter(attrib, opts)
|
95
|
+
create_collection_of_setter(attrib, opts)
|
96
|
+
end
|
97
|
+
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
def merge_belongs_to_association_options(attrib, options = nil)
|
102
|
+
opts = {
|
103
|
+
:foreign_key => attrib.to_s.singularize + '_id',
|
104
|
+
:class_name => attrib.to_s.singularize.camelcase,
|
105
|
+
:proxy_name => attrib.to_s.pluralize
|
106
|
+
}
|
107
|
+
opts.merge!(options) if options.is_a?(Hash)
|
108
|
+
|
109
|
+
# Generate a string for the proxy method call
|
110
|
+
# Assumes that the proxy_owner_method from "proxyable" is available.
|
111
|
+
if opts[:proxy].to_s.empty?
|
112
|
+
opts[:proxy] = if proxy_owner_method
|
113
|
+
"self.#{proxy_owner_method}.#{opts[:proxy_name]}"
|
114
|
+
else
|
115
|
+
opts[:class_name]
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
opts
|
120
|
+
end
|
121
|
+
|
122
|
+
def create_belongs_to_getter(attrib, options)
|
123
|
+
class_eval <<-EOS, __FILE__, __LINE__ + 1
|
124
|
+
def #{attrib}
|
125
|
+
@#{attrib} ||= #{options[:foreign_key]}.nil? ? nil : #{options[:proxy]}.get(self.#{options[:foreign_key]})
|
126
|
+
end
|
127
|
+
EOS
|
128
|
+
end
|
129
|
+
|
130
|
+
def create_belongs_to_setter(attrib, options)
|
131
|
+
class_eval <<-EOS, __FILE__, __LINE__ + 1
|
132
|
+
def #{attrib}=(value)
|
133
|
+
self.#{options[:foreign_key]} = value.nil? ? nil : value.id
|
134
|
+
@#{attrib} = value
|
135
|
+
end
|
136
|
+
EOS
|
137
|
+
end
|
138
|
+
|
139
|
+
### collection_of support methods
|
140
|
+
|
141
|
+
def create_collection_of_property_setter(attrib, options)
|
142
|
+
# ensure CollectionOfProxy is nil, ready to be reloaded on request
|
143
|
+
class_eval <<-EOS, __FILE__, __LINE__ + 1
|
144
|
+
def #{options[:foreign_key]}=(value)
|
145
|
+
@#{attrib} = nil
|
146
|
+
write_attribute("#{options[:foreign_key]}", value)
|
147
|
+
end
|
148
|
+
EOS
|
149
|
+
end
|
150
|
+
|
151
|
+
def create_collection_of_getter(attrib, options)
|
152
|
+
class_eval <<-EOS, __FILE__, __LINE__ + 1
|
153
|
+
def #{attrib}(reload = false)
|
154
|
+
return @#{attrib} unless @#{attrib}.nil? or reload
|
155
|
+
ary = self.#{options[:foreign_key]}.collect{|i| #{options[:proxy]}.get(i)}
|
156
|
+
@#{attrib} = ::CouchRest::Model::CollectionOfProxy.new(ary, find_property('#{options[:foreign_key]}'), self)
|
157
|
+
end
|
158
|
+
EOS
|
159
|
+
end
|
160
|
+
|
161
|
+
def create_collection_of_setter(attrib, options)
|
162
|
+
class_eval <<-EOS, __FILE__, __LINE__ + 1
|
163
|
+
def #{attrib}=(value)
|
164
|
+
@#{attrib} = ::CouchRest::Model::CollectionOfProxy.new(value, find_property('#{options[:foreign_key]}'), self)
|
165
|
+
end
|
166
|
+
EOS
|
167
|
+
end
|
168
|
+
|
169
|
+
end
|
170
|
+
|
171
|
+
end
|
172
|
+
|
173
|
+
# Special proxy for a collection of items so that adding and removing
|
174
|
+
# to the list automatically updates the associated property.
|
175
|
+
class CollectionOfProxy < CastedArray
|
176
|
+
|
177
|
+
def initialize(array, property, parent)
|
178
|
+
(array ||= []).compact!
|
179
|
+
super(array, property, parent)
|
180
|
+
casted_by[casted_by_property.to_s] = [] # replace the original array!
|
181
|
+
array.compact.each do |obj|
|
182
|
+
check_obj(obj)
|
183
|
+
casted_by[casted_by_property.to_s] << obj.id
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
def << obj
|
188
|
+
check_obj(obj)
|
189
|
+
casted_by[casted_by_property.to_s] << obj.id
|
190
|
+
super(obj)
|
191
|
+
end
|
192
|
+
|
193
|
+
def push(obj)
|
194
|
+
check_obj(obj)
|
195
|
+
casted_by[casted_by_property.to_s].push obj.id
|
196
|
+
super(obj)
|
197
|
+
end
|
198
|
+
|
199
|
+
def unshift(obj)
|
200
|
+
check_obj(obj)
|
201
|
+
casted_by[casted_by_property.to_s].unshift obj.id
|
202
|
+
super(obj)
|
203
|
+
end
|
204
|
+
|
205
|
+
def []= index, obj
|
206
|
+
check_obj(obj)
|
207
|
+
casted_by[casted_by_property.to_s][index] = obj.id
|
208
|
+
super(index, obj)
|
209
|
+
end
|
210
|
+
|
211
|
+
def pop
|
212
|
+
casted_by[casted_by_property.to_s].pop
|
213
|
+
super
|
214
|
+
end
|
215
|
+
|
216
|
+
def shift
|
217
|
+
casted_by[casted_by_property.to_s].shift
|
218
|
+
super
|
219
|
+
end
|
220
|
+
|
221
|
+
protected
|
222
|
+
|
223
|
+
def check_obj(obj)
|
224
|
+
raise "Object cannot be added to #{casted_by.class.to_s}##{casted_by_property.to_s} collection unless saved" if obj.new?
|
225
|
+
end
|
226
|
+
|
227
|
+
end
|
228
|
+
|
229
|
+
end
|
230
|
+
|
231
|
+
end
|