Class: CouchRest::ExtendedDocument
- Includes:
- Mixins::AttributeProtection, Mixins::Callbacks, Mixins::ClassProxy, Mixins::Collection, Mixins::DesignDoc, Mixins::DocumentQueries, Mixins::ExtendedAttachments, Mixins::Views
- Defined in:
- lib/couchrest/extended_document.rb
Overview
Same as CouchRest::Document but with properties and validations
Constant Summary collapse
- VERSION =
"1.0.5"
Instance Attribute Summary collapse
-
#casted_by ⇒ Object
Accessors.
Class Method Summary collapse
-
.create(options) ⇒ Object
Defines an instance and save it directly to the database .
-
.create!(options) ⇒ Object
Defines an instance and save it directly to the database .
-
.create_from_database(doc = {}) ⇒ Object
Creates a new instance, bypassing attribute protection.
- .inherited(subklass) ⇒ Object
-
.method_missing(m, *args, &block) ⇒ Object
Temp solution to make the view_by methods available.
-
.subclasses ⇒ Object
Including validation here does not work due to the way inheritance is handled.
-
.timestamps! ⇒ Object
Automatically set
updated_at
andcreated_at
fields on the document whenever saving occurs. -
.unique_id(method = nil, &block) ⇒ Object
Name a method that will be called before the document is first saved, which returns a string to be used for the document’s
_id
.
Instance Method Summary collapse
-
#base_doc ⇒ Object
Gets a reference to the actual document in the DB Calls up to the next document if there is one, Otherwise we’re at the top and we return self.
-
#base_doc? ⇒ Boolean
Checks if we’re the top document.
-
#create(bulk = false) ⇒ Object
Trigger the callbacks (before, after, around) and create the document It’s important to have a create callback since you can’t check if a document was new after you saved it.
-
#create! ⇒ Object
Creates the document in the db.
-
#create_without_callbacks(bulk = false) ⇒ Object
unlike save, create returns the newly created document.
-
#destroy(bulk = false) ⇒ Object
Deletes the document from the database.
-
#initialize(doc = {}, options = {}) ⇒ ExtendedDocument
constructor
A new instance of ExtendedDocument.
-
#properties ⇒ Object
Returns the Class properties.
-
#save(bulk = false) ⇒ Object
Trigger the callbacks (before, after, around) and save the document.
-
#save! ⇒ Object
Saves the document to the db using save.
-
#save_without_callbacks(bulk = false) ⇒ Object
Overridden to set the unique ID.
-
#update(bulk = false) ⇒ Object
Trigger the callbacks (before, after, around) only if the document isn’t new.
-
#update_attributes(hash) ⇒ Object
Takes a hash as argument, and applies the values by using writer methods for each key.
-
#update_attributes_without_saving(hash) ⇒ Object
(also: #attributes=)
Takes a hash as argument, and applies the values by using writer methods for each key.
Methods included from Mixins::AttributeProtection
#accessible_properties, included, #protected_properties, #remove_protected_attributes
Methods included from Mixins::Collection
Methods included from Mixins::ClassProxy
Methods included from Mixins::ExtendedAttachments
#attachment_uri, #attachment_url, #create_attachment, #delete_attachment, #has_attachment?, #read_attachment, #update_attachment
Methods included from Mixins::DesignDoc
Methods included from Mixins::Views
Methods included from Mixins::DocumentQueries
Methods included from Mixins::Callbacks
Constructor Details
#initialize(doc = {}, options = {}) ⇒ ExtendedDocument
Returns a new instance of ExtendedDocument.
60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/couchrest/extended_document.rb', line 60 def initialize(doc = {}, = {}) apply_defaults # defined in CouchRest::Mixins::Properties remove_protected_attributes(doc) unless [:directly_set_attributes] directly_set_attributes(doc) unless doc.nil? super(doc) cast_keys # defined in CouchRest::Mixins::Properties unless self['_id'] && self['_rev'] self['couchrest-type'] = self.class.to_s end after_initialize if respond_to?(:after_initialize) end |
Instance Attribute Details
#casted_by ⇒ Object
Accessors
42 43 44 |
# File 'lib/couchrest/extended_document.rb', line 42 def casted_by @casted_by end |
Class Method Details
.create(options) ⇒ Object
Defines an instance and save it directly to the database
Returns
returns the reloaded document
76 77 78 79 80 |
# File 'lib/couchrest/extended_document.rb', line 76 def self.create() instance = new() instance.create instance end |
.create!(options) ⇒ Object
Defines an instance and save it directly to the database
Returns
returns the reloaded document or raises an exception
86 87 88 89 90 |
# File 'lib/couchrest/extended_document.rb', line 86 def self.create!() instance = new() instance.create! instance end |
.create_from_database(doc = {}) ⇒ Object
Creates a new instance, bypassing attribute protection
Returns
a document instance
55 56 57 58 |
# File 'lib/couchrest/extended_document.rb', line 55 def self.create_from_database(doc = {}) base = (doc['couchrest-type'].blank? || doc['couchrest-type'] == self.to_s) ? self : doc['couchrest-type'].constantize base.new(doc, :directly_set_attributes => true) end |
.inherited(subklass) ⇒ Object
29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/couchrest/extended_document.rb', line 29 def self.inherited(subklass) super subklass.send(:include, CouchRest::Mixins::Properties) subklass.class_eval <<-EOS, __FILE__, __LINE__ + 1 def self.inherited(subklass) super subklass.properties = self.properties.dup end EOS subclasses << subklass end |
.method_missing(m, *args, &block) ⇒ Object
Temp solution to make the view_by methods available
129 130 131 132 133 134 135 136 |
# File 'lib/couchrest/extended_document.rb', line 129 def self.method_missing(m, *args, &block) if has_view?(m) query = args.shift || {} view(m, query, *args, &block) else super end end |
.subclasses ⇒ Object
Including validation here does not work due to the way inheritance is handled. include CouchRest::Validation
25 26 27 |
# File 'lib/couchrest/extended_document.rb', line 25 def self.subclasses @subclasses ||= [] end |
.timestamps! ⇒ Object
Automatically set updated_at
and created_at
fields on the document whenever saving occurs. CouchRest uses a pretty decent time format by default. See Time#to_json
95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/couchrest/extended_document.rb', line 95 def self. class_eval <<-EOS, __FILE__, __LINE__ property(:updated_at, :read_only => true, :type => 'Time', :auto_validation => false) property(:created_at, :read_only => true, :type => 'Time', :auto_validation => false) set_callback :save, :before do |object| object['updated_at'] = Time.now object['created_at'] = object['updated_at'] if object.new? end EOS end |
.unique_id(method = nil, &block) ⇒ Object
Name a method that will be called before the document is first saved, which returns a string to be used for the document’s _id
. Because CouchDB enforces a constraint that each id must be unique, this can be used to enforce eg: uniq usernames. Note that this id must be globally unique across all document types which share a database, so if you’d like to scope uniqueness to this class, you should use the class name as part of the unique id.
114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/couchrest/extended_document.rb', line 114 def self.unique_id method = nil, &block if method define_method :set_unique_id do self['_id'] ||= self.send(method) end elsif block define_method :set_unique_id do uniqid = block.call(self) raise ArgumentError, "unique_id block must not return nil" if uniqid.nil? self['_id'] ||= uniqid end end end |
Instance Method Details
#base_doc ⇒ Object
Gets a reference to the actual document in the DB Calls up to the next document if there is one, Otherwise we’re at the top and we return self
151 152 153 154 |
# File 'lib/couchrest/extended_document.rb', line 151 def base_doc return self if base_doc? @casted_by.base_doc end |
#base_doc? ⇒ Boolean
Checks if we’re the top document
157 158 159 |
# File 'lib/couchrest/extended_document.rb', line 157 def base_doc? !@casted_by end |
#create(bulk = false) ⇒ Object
Trigger the callbacks (before, after, around) and create the document It’s important to have a create callback since you can’t check if a document was new after you saved it
When creating a document, both the create and the save callbacks will be triggered.
193 194 195 196 197 198 199 200 201 |
# File 'lib/couchrest/extended_document.rb', line 193 def create(bulk = false) caught = catch(:halt) do _run_create_callbacks do _run_save_callbacks do create_without_callbacks(bulk) end end end end |
#create! ⇒ Object
Creates the document in the db. Raises an exception if the document is not created properly.
213 214 215 |
# File 'lib/couchrest/extended_document.rb', line 213 def create! raise "#{self.inspect} failed to save" unless self.create end |
#create_without_callbacks(bulk = false) ⇒ Object
unlike save, create returns the newly created document
204 205 206 207 208 209 |
# File 'lib/couchrest/extended_document.rb', line 204 def create_without_callbacks(bulk =false) raise ArgumentError, "a document requires a database to be created to (The document or the #{self.class} default database were not set)" unless database set_unique_id if new? && self.respond_to?(:set_unique_id) result = database.save_doc(self, bulk) (result["ok"] == true) ? self : false end |
#destroy(bulk = false) ⇒ Object
Deletes the document from the database. Runs the :destroy callbacks. Removes the _id
and _rev
fields, preparing the document to be saved to a new _id
.
267 268 269 270 271 272 273 274 275 276 277 278 |
# File 'lib/couchrest/extended_document.rb', line 267 def destroy(bulk=false) caught = catch(:halt) do _run_destroy_callbacks do result = database.delete_doc(self, bulk) if result['ok'] self.delete('_rev') self.delete('_id') end result['ok'] end end end |
#properties ⇒ Object
Returns the Class properties
Returns
- Array
-
the list of properties for the instance
144 145 146 |
# File 'lib/couchrest/extended_document.rb', line 144 def properties self.class.properties end |
#save(bulk = false) ⇒ Object
Trigger the callbacks (before, after, around) and save the document
235 236 237 238 239 240 241 242 243 244 245 |
# File 'lib/couchrest/extended_document.rb', line 235 def save(bulk = false) caught = catch(:halt) do if self.new? _run_save_callbacks do save_without_callbacks(bulk) end else update(bulk) end end end |
#save! ⇒ Object
Saves the document to the db using save. Raises an exception if the document is not saved properly.
259 260 261 262 |
# File 'lib/couchrest/extended_document.rb', line 259 def save! raise "#{self.inspect} failed to save" unless self.save true end |
#save_without_callbacks(bulk = false) ⇒ Object
Overridden to set the unique ID. Returns a boolean value
249 250 251 252 253 254 255 |
# File 'lib/couchrest/extended_document.rb', line 249 def save_without_callbacks(bulk = false) raise ArgumentError, "a document requires a database to be saved to (The document or the #{self.class} default database were not set)" unless database set_unique_id if new? && self.respond_to?(:set_unique_id) result = database.save_doc(self, bulk) mark_as_saved result["ok"] == true end |
#update(bulk = false) ⇒ Object
Trigger the callbacks (before, after, around) only if the document isn’t new
219 220 221 222 223 224 225 226 227 228 229 230 231 |
# File 'lib/couchrest/extended_document.rb', line 219 def update(bulk = false) caught = catch(:halt) do if self.new? save(bulk) else _run_update_callbacks do _run_save_callbacks do save_without_callbacks(bulk) end end end end end |
#update_attributes(hash) ⇒ Object
Takes a hash as argument, and applies the values by using writer methods for each key. Raises a NoMethodError if the corresponding methods are missing. In case of error, no attributes are changed.
178 179 180 181 |
# File 'lib/couchrest/extended_document.rb', line 178 def update_attributes(hash) update_attributes_without_saving hash save end |
#update_attributes_without_saving(hash) ⇒ Object Also known as: attributes=
Takes a hash as argument, and applies the values by using writer methods for each key. It doesn’t save the document at the end. Raises a NoMethodError if the corresponding methods are missing. In case of error, no attributes are changed.
164 165 166 167 168 169 170 171 172 |
# File 'lib/couchrest/extended_document.rb', line 164 def update_attributes_without_saving(hash) # remove attributes that cannot be updated, silently ignoring them # which matches Rails behavior when, for instance, setting created_at. # make a copy, we don't want to change arguments attrs = hash.dup %w[_id _rev created_at updated_at].each {|attr| attrs.delete(attr)} check_properties_exist(attrs) set_attributes(attrs) end |