openlogic-couchrest_model 1.0.0
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/.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
|