Module: Candy::Piece
- Includes:
- Crunch, Crunch::Document, Embeddable
- Included in:
- CandyHash
- Defined in:
- lib/candy/piece.rb
Overview
Handles autopersistence and single-object retrieval for an arbitrary Ruby class. For retrieving many objects, include Candy::Collection somewhere else or use the magic Candy() factory.
Defined Under Namespace
Modules: ClassMethods
Instance Method Summary collapse
-
#==(subject) ⇒ Object
Objects are equal if they point to the same MongoDB record (unless both have IDs of nil, in which case they’re never equal.).
-
#[](key) ⇒ Object
Hash-like getter.
-
#[]=(key, value) ⇒ Object
Hash-like setter.
-
#candy ⇒ Object
Returns the hash of memoized values.
-
#from_candy(hash) ⇒ Object
Unwraps the values passed to us from MongoDB, setting parent attributes on any embedded Candy objects.
-
#id ⇒ Object
Shortcut to the document ID.
-
#initialize(*args, &block) ⇒ Object
Our initializer expects the last argument to be a hash of values.
-
#keys ⇒ Object
Returns the keys we’ve stored.
-
#method_missing(name, *args, &block) ⇒ Object
Candy’s magic ingredient.
-
#refresh ⇒ Object
Clears memoized data so that the next read pulls from the database.
-
#to_candy ⇒ Object
Converts the object into a hash for MongoDB storage.
-
#to_s ⇒ Object
Convenience method for debugging.
-
#values ⇒ Object
Returns the values we’ve stored.
Methods included from Embeddable
Methods included from Crunch::Document
#inc, #inc!, #operate, #operate!, #retrieve, #set, #set!
Methods included from Crunch
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args, &block) ⇒ Object
Candy’s magic ingredient. Assigning to any unknown attribute will push that value into the Mongo collection. Retrieving any unknown attribute will return that value from this record in the Mongo collection.
122 123 124 125 126 127 128 129 130 |
# File 'lib/candy/piece.rb', line 122 def method_missing(name, *args, &block) if name =~ /(.*)=$/ # We're assigning self[$1.to_sym] = args[0] elsif name =~ /(.*)\?$/ # We're asking (self[$1.to_sym] ? true : false) else self[name] end end |
Instance Method Details
#==(subject) ⇒ Object
Objects are equal if they point to the same MongoDB record (unless both have IDs of nil, in which case they’re never equal.)
114 115 116 117 118 |
# File 'lib/candy/piece.rb', line 114 def ==(subject) return false if id.nil? return false unless subject.respond_to?(:id) self.id == subject.id end |
#[](key) ⇒ Object
Hash-like getter. If we don’t have a value yet, we pull from the database looking for one. Fields pulled from the database are keyed as symbols in the hash.
134 135 136 |
# File 'lib/candy/piece.rb', line 134 def [](key) candy[key] end |
#[]=(key, value) ⇒ Object
Hash-like setter. Updates the object’s internal state, and writes to the database if the state has changed. Keys should be passed in as symbols for best consistency with the database.
140 141 142 143 144 |
# File 'lib/candy/piece.rb', line 140 def []=(key, value) property = candy_coat(key, value) # Transform hashes and arrays, and communicate embedding candy[key] = property set key => property end |
#candy ⇒ Object
Returns the hash of memoized values.
108 109 110 |
# File 'lib/candy/piece.rb', line 108 def candy @__candy ||= retrieve || {} end |
#from_candy(hash) ⇒ Object
Unwraps the values passed to us from MongoDB, setting parent attributes on any embedded Candy objects.
176 177 178 179 180 181 182 183 |
# File 'lib/candy/piece.rb', line 176 def from_candy(hash) unwrapped = {} hash.each do |key, value| field = Wrapper.unwrap_key(key) unwrapped[field] = Wrapper.unwrap(value, self, field) end unwrapped end |
#id ⇒ Object
Shortcut to the document ID.
102 103 104 |
# File 'lib/candy/piece.rb', line 102 def id @__candy_id end |
#initialize(*args, &block) ⇒ Object
Our initializer expects the last argument to be a hash of values. If the hash contains an ‘_id’ field we assume we’re being constructed from a MongoDB document and we unwrap the remaining values; otherwise we assume we’re a new document and set any values in the hash as if they were assigned. Any other arguments are not our business and will be passed down the chain.
89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/candy/piece.rb', line 89 def initialize(*args, &block) if args[-1].is_a?(Hash) data = args.pop if data.delete(EMBED_KEY) or @__candy_id = data.delete('_id') # We're an embedded or existing document @__candy = self.from_candy(data) else data.each {|key, value| send("#{key}=", value)} # Assign all the data we're given end end super end |
#keys ⇒ Object
Returns the keys we’ve stored.
153 154 155 |
# File 'lib/candy/piece.rb', line 153 def keys candy.keys end |
#refresh ⇒ Object
Clears memoized data so that the next read pulls from the database.
147 148 149 150 |
# File 'lib/candy/piece.rb', line 147 def refresh @__candy = nil self end |
#to_candy ⇒ Object
Converts the object into a hash for MongoDB storage. Keep in mind that wrapping happens after this stage, so it’s best to use symbols for keys and leave internal arrays and hashes alone.
170 171 172 |
# File 'lib/candy/piece.rb', line 170 def to_candy candy.merge(CLASS_KEY => self.class.name) end |
#to_s ⇒ Object
Convenience method for debugging. Shows the class, the Mongo ID, and the saved state hash.
163 164 165 |
# File 'lib/candy/piece.rb', line 163 def to_s "#{self.class.name} (#{id})#{candy.inspect}" end |
#values ⇒ Object
Returns the values we’ve stored.
158 159 160 |
# File 'lib/candy/piece.rb', line 158 def values candy.values end |