Module: DataMapper::Resource
- Includes:
- Assertions, Transaction, Types
- Defined in:
- lib/dm-core/types.rb,
lib/dm-core/resource.rb
Defined Under Namespace
Modules: Transaction
Instance Attribute Summary collapse
Class Method Summary collapse
-
.append_inclusions(*inclusions) ⇒ TrueClass, FalseClass
Appends a module for inclusion into the model class after DataMapper::Resource.
-
.descendants ⇒ Object
Return all classes that include the DataMapper::Resource module.
- .extra_inclusions ⇒ Object
-
.included(model) ⇒ Object
private
When Resource is included in a class this method makes sure it gets all the methods.
Instance Method Summary collapse
-
#attribute_dirty?(name) ⇒ Boolean
Checks if the attribute is dirty.
-
#attribute_get(name) ⇒ Object
returns the value of the attribute.
-
#attribute_loaded?(name) ⇒ Boolean
Checks if the attribute has been loaded.
-
#attribute_set(name, value) ⇒ Object
sets the value of the attribute and marks the attribute as dirty if it has been changed so that it may be saved.
-
#attributes ⇒ Object
all the attributes of the model.
-
#attributes=(values_hash) ⇒ Object
Mass assign of attributes.
-
#destroy ⇒ Object
destroy the instance, remove it from the repository.
-
#dirty? ⇒ Boolean
Checks if the class is dirty.
-
#dirty_attributes ⇒ Object
private
Hash of attributes that have been marked dirty.
-
#eql?(other) ⇒ Boolean
(also: #==)
Compares if its the same object or if attributes are equal.
-
#hash ⇒ Object
Computes a hash for the resource.
-
#id ⇒ Object
default id method to return the resource id when there is a single key, and the model was defined with a primary key named something other than id.
-
#inspect ⇒ Object
Inspection of the class name and the attributes.
- #key ⇒ Object
-
#loaded_attributes ⇒ Object
fetches all the names of the attributes that have been loaded, even if they are lazy but have been called.
-
#new_record? ⇒ Boolean
Checks if the model has been saved.
-
#original_values ⇒ Object
set of original values of properties.
-
#pretty_print(pp) ⇒ Object
TODO docs.
- #readonly! ⇒ Object
- #readonly? ⇒ Boolean
-
#reload ⇒ Object
Reload association and all child association.
-
#reload_attributes(*attributes) ⇒ Object
Reload specific attributes.
-
#repository ⇒ Object
Returns <Repository>:: the respository this resource belongs to in the context of a collection OR in the class’s context.
-
#save(context = :default) ⇒ Object
save the instance to the data-store.
-
#to_query(query = {}) ⇒ Object
TODO: add docs.
-
#update_attributes(hash, *update_only) ⇒ Object
Updates attributes and saves model.
Methods included from Transaction
Methods included from Assertions
Instance Attribute Details
#collection ⇒ Object
424 425 426 427 428 |
# File 'lib/dm-core/resource.rb', line 424 def collection @collection ||= if query = to_query Collection.new(query) { |c| c << self } end end |
Class Method Details
.append_inclusions(*inclusions) ⇒ TrueClass, FalseClass
Appends a module for inclusion into the model class after DataMapper::Resource.
This is a useful way to extend DataMapper::Resource while still retaining a self.included method.
-
23 24 25 26 |
# File 'lib/dm-core/resource.rb', line 23 def self.append_inclusions(*inclusions) extra_inclusions.concat inclusions true end |
.descendants ⇒ Object
Return all classes that include the DataMapper::Resource module
Returns
- Set
-
a set containing the including classes
Example
Class Foo
include DataMapper::Resource
end
DataMapper::Resource.descendants.to_a.first == Foo
-
64 65 66 |
# File 'lib/dm-core/resource.rb', line 64 def self.descendants @descendants ||= Set.new end |
.extra_inclusions ⇒ Object
28 29 30 |
# File 'lib/dm-core/resource.rb', line 28 def self.extra_inclusions @extra_inclusions ||= [] end |
.included(model) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
When Resource is included in a class this method makes sure it gets all the methods
-
37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/dm-core/resource.rb', line 37 def self.included(model) model.extend Model model.extend ClassMethods if defined?(ClassMethods) model.const_set('Resource', self) unless model.const_defined?('Resource') extra_inclusions.each { |inclusion| model.send(:include, inclusion) } descendants << model class << model @_valid_model = false attr_reader :_valid_model end end |
Instance Method Details
#attribute_dirty?(name) ⇒ Boolean
Checks if the attribute is dirty
Parameters
- name<Symbol>
-
name of attribute
Returns
- True
-
returns if attribute is dirty
–
420 421 422 |
# File 'lib/dm-core/resource.rb', line 420 def attribute_dirty?(name) dirty_attributes.has_key?(properties[name]) end |
#attribute_get(name) ⇒ Object
returns the value of the attribute. Do not read from instance variables directly, but use this method. This method handels the lazy loading the attribute and returning of defaults if nessesary.
Parameters
- name<Symbol>
-
name attribute to lookup
Returns
- <Types>
-
the value stored at that given attribute, nil if none, and default if necessary
Example
Class Foo
include DataMapper::Resource
property :first_name, String
property :last_name, String
def full_name
"#{attribute_get(:first_name)} #{attribute_get(:last_name)}"
end
# using the shorter syntax
def name_for_address_book
"#{last_name}, #{first_name}"
end
end
-
105 106 107 |
# File 'lib/dm-core/resource.rb', line 105 def attribute_get(name) properties[name].get(self) end |
#attribute_loaded?(name) ⇒ Boolean
Checks if the attribute has been loaded
Example
class Foo
include DataMapper::Resource
property :name, String
property :description, Text, :lazy => false
end
Foo.new.attribute_loaded?(:description) # will return false
–
332 333 334 |
# File 'lib/dm-core/resource.rb', line 332 def attribute_loaded?(name) instance_variable_defined?(properties[name].instance_variable_name) end |
#attribute_set(name, value) ⇒ Object
sets the value of the attribute and marks the attribute as dirty if it has been changed so that it may be saved. Do not set from instance variables directly, but use this method. This method handels the lazy loading the property and returning of defaults if nessesary.
Parameters
- name<Symbol>
-
name attribute to set
- value<Type>
-
value to store at that location
Returns
- <Types>
-
the value stored at that given attribute, nil if none, and default if necessary
Example
Class Foo
include DataMapper::Resource
property :first_name, String
property :last_name, String
def full_name(name)
name = name.split(' ')
attribute_set(:first_name, name[0])
attribute_set(:last_name, name[1])
end
# using the shorter syntax
def name_from_address_book(name)
name = name.split(', ')
first_name = name[1]
last_name = name[0]
end
end
-
146 147 148 |
# File 'lib/dm-core/resource.rb', line 146 def attribute_set(name, value) properties[name].set(self, value) end |
#attributes ⇒ Object
482 483 484 485 486 |
# File 'lib/dm-core/resource.rb', line 482 def attributes properties.map do |p| [p.name, send(p.getter)] if p.reader_visibility == :public end.compact.to_hash end |
#attributes=(values_hash) ⇒ Object
495 496 497 498 499 500 501 502 503 504 505 |
# File 'lib/dm-core/resource.rb', line 495 def attributes=(values_hash) values_hash.each_pair do |k,v| setter = "#{k.to_s.sub(/\?\z/, '')}=" if respond_to?(setter) send(setter, v) else raise NameError, "#{setter} is not a public property" end end end |
#destroy ⇒ Object
destroy the instance, remove it from the repository
Returns
- <True, False>
-
results of the destruction
–
302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 |
# File 'lib/dm-core/resource.rb', line 302 def destroy return false if new_record? return false unless repository.delete(to_query) @new_record = true repository.identity_map(model).delete(key) original_values.clear properties.each do |property| # We'll set the original value to nil as if we had a new record original_values[property.name] = nil if attribute_loaded?(property.name) end true end |
#dirty? ⇒ Boolean
Checks if the class is dirty
Returns
- True
-
returns if class is dirty
–
406 407 408 |
# File 'lib/dm-core/resource.rb', line 406 def dirty? dirty_attributes.any? end |
#dirty_attributes ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Hash of attributes that have been marked dirty
Returns
- Hash
-
attributes that have been marked dirty
–
376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 |
# File 'lib/dm-core/resource.rb', line 376 def dirty_attributes dirty_attributes = {} properties = self.properties original_values.each do |name, old_value| property = properties[name] new_value = property.get!(self) dirty = case property.track when :hash then old_value != new_value.hash else property.value(old_value) != property.value(new_value) end if dirty property.hash dirty_attributes[property] = property.value(new_value) end end dirty_attributes end |
#eql?(other) ⇒ Boolean Also known as: ==
Compares if its the same object or if attributes are equal
Parameters
- other<Object>
-
Object to compare to
Returns
- <True>
-
the outcome of the comparison as a boolean
-
160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/dm-core/resource.rb', line 160 def eql?(other) return true if object_id == other.object_id return false unless other.kind_of?(model) return true if repository == other.repository && key == other.key properties.each do |property| return false if property.get!(self) != property.get!(other) end true end |
#hash ⇒ Object
Computes a hash for the resource
Returns
- <Integer>
-
the hash value of the resource
-
181 182 183 |
# File 'lib/dm-core/resource.rb', line 181 def hash model.hash + key.hash end |
#id ⇒ Object
default id method to return the resource id when there is a single key, and the model was defined with a primary key named something other than id
Returns
<Array, Key> key or keys
–
244 245 246 247 |
# File 'lib/dm-core/resource.rb', line 244 def id key = self.key key.first if key.size == 1 end |
#inspect ⇒ Object
Inspection of the class name and the attributes
Returns
- <String>
-
with the class name, attributes with their values
Example
>> Foo.new
> #<Foo name=nil updated_at=nil created_at=nil id=nil>
-
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 |
# File 'lib/dm-core/resource.rb', line 197 def inspect attrs = [] properties.each do |property| value = if property.lazy? && !attribute_loaded?(property.name) && !new_record? '<not loaded>' else send(property.getter).inspect end attrs << "#{property.name}=#{value}" end "#<#{model.name} #{attrs * ' '}>" end |
#key ⇒ Object
249 250 251 252 253 |
# File 'lib/dm-core/resource.rb', line 249 def key key_properties.map do |property| original_values[property.name] || property.get!(self) end end |
#loaded_attributes ⇒ Object
fetches all the names of the attributes that have been loaded, even if they are lazy but have been called
Returns
- Array
-
names of attributes that have been loaded
Example
class Foo
include DataMapper::Resource
property :name, String
property :description, Text, :lazy => false
end
Foo.new.loaded_attributes # returns [:name]
–
354 355 356 |
# File 'lib/dm-core/resource.rb', line 354 def loaded_attributes properties.map{|p| p.name if attribute_loaded?(p.name)}.compact end |
#new_record? ⇒ Boolean
Checks if the model has been saved
Returns
- True
-
status if the model is new
–
471 472 473 |
# File 'lib/dm-core/resource.rb', line 471 def new_record? !defined?(@new_record) || @new_record end |
#original_values ⇒ Object
set of original values of properties
Returns
- Hash
-
original values of properties
–
365 366 367 |
# File 'lib/dm-core/resource.rb', line 365 def original_values @original_values ||= {} end |
#pretty_print(pp) ⇒ Object
TODO docs
214 215 216 217 218 219 220 221 222 223 |
# File 'lib/dm-core/resource.rb', line 214 def pretty_print(pp) pp.group(1, "#<#{model.name}", ">") do pp.breakable pp.seplist(attributes.to_a) do |k_v| pp.text k_v[0].to_s pp.text " = " pp.pp k_v[1] end end end |
#readonly! ⇒ Object
255 256 257 |
# File 'lib/dm-core/resource.rb', line 255 def readonly! @readonly = true end |
#readonly? ⇒ Boolean
259 260 261 |
# File 'lib/dm-core/resource.rb', line 259 def readonly? @readonly == true end |
#reload ⇒ Object
Reload association and all child association
Returns
- self
-
returns the class itself
–
437 438 439 440 441 442 443 444 |
# File 'lib/dm-core/resource.rb', line 437 def reload unless new_record? reload_attributes(*loaded_attributes) (parent_associations + child_associations).each { |association| association.reload } end self end |
#reload_attributes(*attributes) ⇒ Object
Reload specific attributes
Parameters
- *attributes<Array>
-
name of attribute
Returns
- self
-
returns the class itself
–
456 457 458 459 460 461 462 |
# File 'lib/dm-core/resource.rb', line 456 def reload_attributes(*attributes) unless attributes.empty? || new_record? collection.reload(:fields => attributes) end self end |
#repository ⇒ Object
Returns
- <Repository>
-
the respository this resource belongs to in the context of a collection OR in the class’s context
231 232 233 |
# File 'lib/dm-core/resource.rb', line 231 def repository @repository || model.repository end |
#save(context = :default) ⇒ Object
save the instance to the data-store
Returns
- <True, False>
-
results of the save
– #public
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 |
# File 'lib/dm-core/resource.rb', line 272 def save(context = :default) # Takes a context, but does nothing with it. This is to maintain the # same API through out all of dm-more. dm-validations requires a # context to be passed associations_saved = false child_associations.each { |a| associations_saved |= a.save } saved = if dirty? || (new_record? && key_properties.any? { |p| p.serial? }) new_record? ? create : update end if saved original_values.clear end parent_associations.each { |a| associations_saved |= a.save } # We should return true if the model (or any of its associations) # were saved. (saved | associations_saved) == true end |
#to_query(query = {}) ⇒ Object
TODO: add docs
529 530 531 |
# File 'lib/dm-core/resource.rb', line 529 def to_query(query = {}) model.to_query(repository, key, query) unless new_record? end |
#update_attributes(hash, *update_only) ⇒ Object
Updates attributes and saves model
Parameters
attributes<Hash> Attributes to be updated keys<Symbol, String, Array> keys of Hash to update (others won’t be updated)
Returns
<TrueClass, FalseClass> if model got saved or not
-
518 519 520 521 522 523 524 525 526 |
# File 'lib/dm-core/resource.rb', line 518 def update_attributes(hash, *update_only) unless hash.is_a?(Hash) raise ArgumentError, "Expecting the first parameter of " + "update_attributes to be a hash; got #{hash.inspect}" end loop_thru = update_only.empty? ? hash.keys : update_only loop_thru.each { |attr| send("#{attr}=", hash[attr]) } save end |