Class: CouchRest::ExtendedDocument

Inherits:
Document show all
Includes:
Callbacks, Mixins::ClassProxy, Mixins::Collection, Mixins::DesignDoc, Mixins::DocumentQueries, Mixins::ExtendedAttachments, Mixins::Views
Defined in:
lib/couchrest/more/extended_document.rb

Overview

Same as CouchRest::Document but with properties and validations

Instance Attribute Summary collapse

Attributes inherited from Document

#database

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Mixins::Collection

included

Methods included from Mixins::ClassProxy

included

Methods included from Mixins::ExtendedAttachments

#attachment_uri, #attachment_url, #create_attachment, #delete_attachment, #has_attachment?, #read_attachment, #update_attachment

Methods included from Mixins::DesignDoc

included

Methods included from Mixins::Views

included

Methods included from Mixins::DocumentQueries

included

Methods included from Callbacks

included, #method_missing, #run_callbacks

Methods inherited from Document

#copy, #id, #new_document?, #rev, #uri, use_database

Methods included from Mixins::Attachments

#delete_attachment, #fetch_attachment, #put_attachment

Methods inherited from Response

#[], #[]=

Methods inherited from Hash

===

Constructor Details

#initialize(passed_keys = {}) ⇒ ExtendedDocument

Returns a new instance of ExtendedDocument.



41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/couchrest/more/extended_document.rb', line 41

def initialize(passed_keys={})
  apply_defaults # defined in CouchRest::Mixins::Properties
  passed_keys.each do |k,v|
    if self.respond_to?("#{k}=")
      self.send("#{k}=", passed_keys.delete(k))
    end
  end if passed_keys
  super
  cast_keys      # defined in CouchRest::Mixins::Properties
  unless self['_id'] && self['_rev']
    self['couchrest-type'] = self.class.to_s
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class CouchRest::Callbacks

Instance Attribute Details

#casted_byObject

Accessors



33
34
35
# File 'lib/couchrest/more/extended_document.rb', line 33

def casted_by
  @casted_by
end

Class Method Details

.inherited(subklass) ⇒ Object



22
23
24
25
26
27
28
29
30
# File 'lib/couchrest/more/extended_document.rb', line 22

def self.inherited(subklass)
  subklass.send(:include, CouchRest::Mixins::Properties)
  subklass.class_eval "    def self.inherited(subklass)\n      subklass.properties = self.properties.dup\n    end\n  EOS\n  subclasses << subklass\nend\n", __FILE__, __LINE__

.method_missing(m, *args, &block) ⇒ Object

Temp solution to make the view_by methods available



95
96
97
98
99
100
101
102
# File 'lib/couchrest/more/extended_document.rb', line 95

def self.method_missing(m, *args, &block)
  if has_view?(m)
    query = args.shift || {}
    view(m, query, *args, &block)
  else
    super
  end
end

.subclassesObject



18
19
20
# File 'lib/couchrest/more/extended_document.rb', line 18

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



61
62
63
64
65
66
67
68
69
70
71
# File 'lib/couchrest/more/extended_document.rb', line 61

def self.timestamps!
  class_eval "    property(:updated_at, :read_only => true, :cast_as => 'Time', :auto_validation => false)\n    property(:created_at, :read_only => true, :cast_as => 'Time', :auto_validation => false)\n    \n    save_callback :before do |object|\n      object['updated_at'] = Time.now\n      object['created_at'] = object['updated_at'] if object.new_document?\n    end\n  EOS\nend\n", __FILE__, __LINE__

.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.



80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/couchrest/more/extended_document.rb', line 80

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

#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.



143
144
145
146
147
148
149
150
151
# File 'lib/couchrest/more/extended_document.rb', line 143

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.



163
164
165
# File 'lib/couchrest/more/extended_document.rb', line 163

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

Raises:

  • (ArgumentError)


154
155
156
157
158
159
# File 'lib/couchrest/more/extended_document.rb', line 154

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_document? && 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.



215
216
217
218
219
220
221
222
223
224
225
226
# File 'lib/couchrest/more/extended_document.rb', line 215

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

#propertiesObject

Returns the Class properties

Returns

Array

the list of properties for the instance



110
111
112
# File 'lib/couchrest/more/extended_document.rb', line 110

def properties
  self.class.properties
end

#save(bulk = false) ⇒ Object

Trigger the callbacks (before, after, around) and save the document



185
186
187
188
189
190
191
192
193
194
195
# File 'lib/couchrest/more/extended_document.rb', line 185

def save(bulk = false)
  caught = catch(:halt)  do
    if self.new_document?
      _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.



208
209
210
# File 'lib/couchrest/more/extended_document.rb', line 208

def save!
  raise "#{self.inspect} failed to save" unless self.save
end

#save_without_callbacks(bulk = false) ⇒ Object

Overridden to set the unique ID. Returns a boolean value

Raises:

  • (ArgumentError)


199
200
201
202
203
204
# File 'lib/couchrest/more/extended_document.rb', line 199

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_document? && self.respond_to?(:set_unique_id)
  result = database.save_doc(self, bulk)
  result["ok"] == true
end

#update(bulk = false) ⇒ Object

Trigger the callbacks (before, after, around) only if the document isn’t new



169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/couchrest/more/extended_document.rb', line 169

def update(bulk = false)
  caught = catch(:halt)  do
    if self.new_document?
      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.



129
130
131
132
# File 'lib/couchrest/more/extended_document.rb', line 129

def update_attributes(hash)
  update_attributes_without_saving hash
  save
end

#update_attributes_without_saving(hash) ⇒ Object

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.



117
118
119
120
121
122
123
124
# File 'lib/couchrest/more/extended_document.rb', line 117

def update_attributes_without_saving(hash)
  hash.each do |k, v|
    raise NoMethodError, "#{k}= method not available, use property :#{k}" unless self.respond_to?("#{k}=")
  end      
  hash.each do |k, v|
    self.send("#{k}=",v)
  end
end