Module: DataMapper::Resource
- Extended by:
- Deprecate
- Includes:
- Assertions
- Defined in:
- lib/dm-core/resource.rb,
lib/dm-core/backwards.rb,
lib/dm-core/resource/persistence_state.rb,
lib/dm-core/resource/persistence_state/clean.rb,
lib/dm-core/resource/persistence_state/dirty.rb,
lib/dm-core/resource/persistence_state/deleted.rb,
lib/dm-core/resource/persistence_state/transient.rb,
lib/dm-core/resource/persistence_state/immutable.rb,
lib/dm-core/resource/persistence_state/persisted.rb
Defined Under Namespace
Classes: PersistenceState
Class Method Summary (collapse)
-
+ (Object) included(model)
private
Makes sure a class gets all the methods when it includes Resource.
Instance Method Summary (collapse)
-
- (Integer) <=>(other)
Compares two Resources to allow them to be sorted.
-
- (Boolean) ==(other)
Compares another Resource for equivalency.
-
- (undefined) after_create_hook
protected
private
Method for hooking callbacks after resource creation.
-
- (undefined) after_destroy_hook
protected
private
Method for hooking callbacks after resource destruction.
-
- (undefined) after_save_hook
protected
private
Method for hooking callbacks after resource saving.
-
- (undefined) after_update_hook
protected
private
Method for hooking callbacks after resource updating.
-
- (Boolean) attribute_dirty?(name)
Checks if an attribute has unsaved changes.
-
- (Object) attribute_get(name)
(also: #[])
Returns the value of the attribute.
-
- (Boolean) attribute_loaded?(name)
private
Checks if an attribute has been loaded from the repository.
-
- (undefined) attribute_set(name, value)
(also: #[]=)
Sets the value of the attribute and marks the attribute as dirty if it has been changed so that it may be saved.
-
- (Hash) attributes(key_on = :name)
Gets all the attributes of the Resource instance.
-
- (Hash) attributes=(attributes)
Assign values to multiple attributes in one call (mass assignment).
-
- (undefined) before_create_hook
protected
private
Method for hooking callbacks before resource creation.
-
- (undefined) before_destroy_hook
protected
private
Method for hooking callbacks before resource destruction.
-
- (undefined) before_save_hook
protected
private
Method for hooking callbacks before resource saving.
-
- (undefined) before_update_hook
protected
private
Method for hooking callbacks before resource updating.
-
- (Boolean) clean?
Checks if the resource has no changes to save.
-
- (nil, Collection) collection
private
Returns the Collection the Resource is associated with.
-
- (nil, Collection) collection=(collection)
private
Associates a Resource to a Collection.
-
- (Collection) collection_for_self
private
Return a collection including the current resource only.
-
- (Boolean) destroy
Destroy the instance, remove it from the repository.
-
- (Boolean) destroy!
Destroy the instance, remove it from the repository, bypassing hooks.
-
- (Boolean) destroyed?
Checks if this Resource instance is destroyed.
-
- (Boolean) dirty?
Checks if the resource has unsaved changes.
-
- (Hash) dirty_attributes
Hash of attributes that have unsaved changes.
-
- (Boolean) eql?(other)
Compares another Resource for equality.
-
- (Object) hash
private
Returns hash value of the object.
-
- (String) inspect
Get a Human-readable representation of this Resource instance.
-
- (Array(Key)) key
Retrieve the key(s) for this resource.
-
- (Boolean) new?
Checks if this Resource instance is new.
-
- (Hash) original_attributes
Hash of original values of attributes that have unsaved changes.
-
- (Resource::PersistenceState) persistence_state
private
Get the persisted state for the resource.
-
- (undefined) persistence_state=(state)
private
Set the persisted state for the resource.
-
- (Boolean) persistence_state?
private
Test if the persisted state is set.
-
- (Query) query
Returns a Query that will match the resource.
-
- (Boolean) raise_on_save_failure
Return if Resource#save should raise an exception on save failures (per-resource).
-
- (Boolean) raise_on_save_failure=(raise_on_save_failure)
Specify if Resource#save should raise an exception on save failures (per-resource).
-
- (Boolean) readonly?
Checks if this Resource instance is readonly.
-
- (Resource) reload
Reloads association and all child association.
-
- (Repository) repository
Repository this resource belongs to in the context of this collection or of the resource's class.
-
- (Boolean) save
Save the instance and loaded, dirty associations to the data-store.
-
- (Boolean) save!
Save the instance and loaded, dirty associations to the data-store, bypassing hooks.
-
- (Boolean) saved?
Checks if this Resource instance is saved.
-
- (Boolean) update(attributes)
Updates attributes and saves this Resource instance.
-
- (Boolean) update!(attributes)
Updates attributes and saves this Resource instance, bypassing hooks.
- - (Object) update_attributes(attributes = {}, *allowed) deprecated Deprecated.
Methods included from Deprecate
Methods included from Assertions
Class Method Details
+ (Object) included(model)
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.
Makes sure a class gets all the methods when it includes Resource
Note that including this module into an anonymous class will leave the model descendant tracking mechanism with no possibility to reliably track the anonymous model across code reloads. This means that DescendantSet will currently leak memory in scenarios where anonymous models are reloaded multiple times (as is the case in dm-rails development mode for example).
55 56 57 58 |
# File 'lib/dm-core/resource.rb', line 55 def self.included(model) model.extend Model super end |
Instance Method Details
- (Integer) <=>(other)
Compares two Resources to allow them to be sorted
484 485 486 487 488 489 490 491 492 493 494 |
# File 'lib/dm-core/resource.rb', line 484 def <=>(other) model = self.model unless other.kind_of?(model.base_model) raise ArgumentError, "Cannot compare a #{other.class} instance with a #{model} instance" end model.default_order(repository_name).each do |direction| cmp = direction.get(self) <=> direction.get(other) return cmp if cmp.nonzero? end 0 end |
- (Boolean) ==(other)
Compares another Resource for equivalency
Resource is equivalent to other if they are the same object (identical object_id) or all of their attribute are equivalent
467 468 469 470 471 |
# File 'lib/dm-core/resource.rb', line 467 def ==(other) return true if equal?(other) return false unless other.kind_of?(Resource) && model.base_model.equal?(other.model.base_model) cmp?(other, :==) end |
- (undefined) after_create_hook (protected)
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.
Method for hooking callbacks after resource creation
682 683 684 |
# File 'lib/dm-core/resource.rb', line 682 def after_create_hook execute_hooks_for(:after, :create) end |
- (undefined) after_destroy_hook (protected)
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.
Method for hooking callbacks after resource destruction
718 719 720 |
# File 'lib/dm-core/resource.rb', line 718 def after_destroy_hook execute_hooks_for(:after, :destroy) end |
- (undefined) after_save_hook (protected)
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.
Method for hooking callbacks after resource saving
664 665 666 |
# File 'lib/dm-core/resource.rb', line 664 def after_save_hook execute_hooks_for(:after, :save) end |
- (undefined) after_update_hook (protected)
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.
Method for hooking callbacks after resource updating
700 701 702 |
# File 'lib/dm-core/resource.rb', line 700 def after_update_hook execute_hooks_for(:after, :update) end |
- (Boolean) attribute_dirty?(name)
Checks if an attribute has unsaved changes
579 580 581 |
# File 'lib/dm-core/resource.rb', line 579 def attribute_dirty?(name) dirty_attributes.key?(properties[name]) end |
- (Object) attribute_get(name) Also known as: []
Returns the value of the attribute.
Do not read from instance variables directly, but use this method. This method handles lazy loading the attribute and returning of defaults if nessesary.
225 226 227 228 |
# File 'lib/dm-core/resource.rb', line 225 def attribute_get(name) property = properties[name] persistence_state.get(property) if property end |
- (Boolean) attribute_loaded?(name)
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.
Checks if an attribute has been loaded from the repository
566 567 568 |
# File 'lib/dm-core/resource.rb', line 566 def attribute_loaded?(name) properties[name].loaded?(self) end |
- (undefined) attribute_set(name, value) Also known as: []=
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 handles the lazy loading the property and returning of defaults if nessesary.
267 268 269 270 |
# File 'lib/dm-core/resource.rb', line 267 def attribute_set(name, value) property = properties[name] self.persistence_state = persistence_state.set(property, value) if property end |
- (Hash) attributes(key_on = :name)
Gets all the attributes of the Resource instance
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 |
# File 'lib/dm-core/resource.rb', line 285 def attributes(key_on = :name) attributes = {} lazy_load(properties) fields.each do |property| if model.public_method_defined?(name = property.name) key = case key_on when :name then name when :field then property.field else property end attributes[key] = __send__(name) end end attributes end |
- (Hash) attributes=(attributes)
Assign values to multiple attributes in one call (mass assignment)
313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 |
# File 'lib/dm-core/resource.rb', line 313 def attributes=(attributes) model = self.model attributes.each do |name, value| case name when String, Symbol if model.allowed_writer_methods.include?(setter = "#{name}=") __send__(setter, value) else raise ArgumentError, "The attribute '#{name}' is not accessible in #{model}" end when Associations::Relationship, Property self.persistence_state = persistence_state.set(name, value) end end end |
- (undefined) before_create_hook (protected)
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.
Method for hooking callbacks before resource creation
673 674 675 |
# File 'lib/dm-core/resource.rb', line 673 def before_create_hook execute_hooks_for(:before, :create) end |
- (undefined) before_destroy_hook (protected)
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.
Method for hooking callbacks before resource destruction
709 710 711 |
# File 'lib/dm-core/resource.rb', line 709 def before_destroy_hook execute_hooks_for(:before, :destroy) end |
- (undefined) before_save_hook (protected)
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.
Method for hooking callbacks before resource saving
655 656 657 |
# File 'lib/dm-core/resource.rb', line 655 def before_save_hook execute_hooks_for(:before, :save) end |
- (undefined) before_update_hook (protected)
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.
Method for hooking callbacks before resource updating
691 692 693 |
# File 'lib/dm-core/resource.rb', line 691 def before_update_hook execute_hooks_for(:before, :update) end |
- (Boolean) clean?
Checks if the resource has no changes to save
167 168 169 170 |
# File 'lib/dm-core/resource.rb', line 167 def clean? persistence_state.kind_of?(PersistenceState::Clean) || persistence_state.kind_of?(PersistenceState::Immutable) end |
- (nil, Collection) collection
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.
Returns the Collection the Resource is associated with
608 609 610 611 |
# File 'lib/dm-core/resource.rb', line 608 def collection return @_collection if @_collection || new? || readonly? collection_for_self end |
- (nil, Collection) collection=(collection)
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.
Associates a Resource to a Collection
624 625 626 |
# File 'lib/dm-core/resource.rb', line 624 def collection=(collection) @_collection = collection end |
- (Collection) collection_for_self
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.
Return a collection including the current resource only
634 635 636 |
# File 'lib/dm-core/resource.rb', line 634 def collection_for_self Collection.new(query, [ self ]) end |
- (Boolean) destroy
Destroy the instance, remove it from the repository
415 416 417 418 419 420 421 422 423 |
# File 'lib/dm-core/resource.rb', line 415 def destroy return true if destroyed? catch :halt do before_destroy_hook _destroy after_destroy_hook end destroyed? end |
- (Boolean) destroy!
Destroy the instance, remove it from the repository, bypassing hooks
431 432 433 434 435 |
# File 'lib/dm-core/resource.rb', line 431 def destroy! return true if destroyed? _destroy(false) destroyed? end |
- (Boolean) destroyed?
Checks if this Resource instance is destroyed
157 158 159 |
# File 'lib/dm-core/resource.rb', line 157 def destroyed? readonly? && !key.nil? end |
- (Boolean) dirty?
Checks if the resource has unsaved changes
178 179 180 181 182 |
# File 'lib/dm-core/resource.rb', line 178 def dirty? run_once(true) do dirty_self? || dirty_parents? || dirty_children? end end |
- (Hash) dirty_attributes
Hash of attributes that have unsaved changes
589 590 591 592 593 594 595 596 597 598 |
# File 'lib/dm-core/resource.rb', line 589 def dirty_attributes dirty_attributes = {} original_attributes.each_key do |property| next unless property.respond_to?(:dump) dirty_attributes[property] = property.dump(property.get!(self)) end dirty_attributes end |
- (Boolean) eql?(other)
Compares another Resource for equality
Resource is equal to other if they are the same object (identical object_id) or if they are both of the *same model* and all of their attributes are equivalent
450 451 452 453 |
# File 'lib/dm-core/resource.rb', line 450 def eql?(other) return true if equal?(other) instance_of?(other.class) && cmp?(other, :eql?) end |
- (Object) hash
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.
Returns hash value of the object. Two objects with the same hash value assumed equal (using eql? method)
DataMapper resources are equal when their models have the same hash and they have the same set of properties
When used as key in a Hash or Hash subclass, objects are compared by eql? and thus hash value has direct effect on lookup
506 507 508 |
# File 'lib/dm-core/resource.rb', line 506 def hash model.hash ^ key.hash end |
- (String) inspect
Get a Human-readable representation of this Resource instance
Foo.new #=> #<Foo name=nil updated_at=nil created_at=nil id=nil>
518 519 520 521 522 523 524 525 526 527 528 529 530 531 |
# File 'lib/dm-core/resource.rb', line 518 def inspect # TODO: display relationship values attrs = properties.map do |property| value = if new? || property.loaded?(self) property.get!(self).inspect else '<not loaded>' end "#{property.instance_variable_name}=#{value}" end "#<#{model.name} #{attrs.join(' ')}>" end |
- (Array(Key)) key
Retrieve the key(s) for this resource.
This always returns the persisted key value, even if the key is changed and not yet persisted. This is done so all relations still work.
118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/dm-core/resource.rb', line 118 def key return @_key if defined?(@_key) model_key = model.key(repository_name) key = model_key.map do |property| original_attributes[property] || (property.loaded?(self) ? property.get!(self) : nil) end # only memoize a valid key @_key = key if model_key.valid?(key) end |
- (Boolean) new?
Checks if this Resource instance is new
137 138 139 |
# File 'lib/dm-core/resource.rb', line 137 def new? persistence_state.kind_of?(PersistenceState::Transient) end |
- (Hash) original_attributes
Hash of original values of attributes that have unsaved changes
539 540 541 542 543 544 545 |
# File 'lib/dm-core/resource.rb', line 539 def original_attributes if persistence_state.respond_to?(:original_attributes) persistence_state.original_attributes.dup.freeze else {}.freeze end end |
- (Resource::PersistenceState) persistence_state
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.
Get the persisted state for the resource
69 70 71 |
# File 'lib/dm-core/resource.rb', line 69 def persistence_state @_persistence_state ||= Resource::PersistenceState::Transient.new(self) end |
- (undefined) persistence_state=(state)
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.
Set the persisted state for the resource
81 82 83 |
# File 'lib/dm-core/resource.rb', line 81 def persistence_state=(state) @_persistence_state = state end |
- (Boolean) persistence_state?
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.
Test if the persisted state is set
91 92 93 |
# File 'lib/dm-core/resource.rb', line 91 def persistence_state? defined?(@_persistence_state) ? true : false end |
- (Query) query
Returns a Query that will match the resource
644 645 646 |
# File 'lib/dm-core/resource.rb', line 644 def query repository.new_query(model, :fields => fields, :conditions => conditions) end |
- (Boolean) raise_on_save_failure
Return if Resource#save should raise an exception on save failures (per-resource)
This delegates to model.raise_on_save_failure by default.
user.raise_on_save_failure # => false
15 16 17 18 19 20 21 |
# File 'lib/dm-core/resource.rb', line 15 def raise_on_save_failure if defined?(@raise_on_save_failure) @raise_on_save_failure else model.raise_on_save_failure end end |
- (Boolean) raise_on_save_failure=(raise_on_save_failure)
Specify if Resource#save should raise an exception on save failures (per-resource)
32 33 34 |
# File 'lib/dm-core/resource.rb', line 32 def raise_on_save_failure=(raise_on_save_failure) @raise_on_save_failure = raise_on_save_failure end |
- (Boolean) readonly?
Checks if this Resource instance is readonly
190 191 192 |
# File 'lib/dm-core/resource.rb', line 190 def readonly? persistence_state.kind_of?(PersistenceState::Immutable) end |
- (Resource) reload
Reloads association and all child association
This is accomplished by resetting the Resource key to it's original value, and then removing all the ivars for properties and relationships. On the next access of those ivars, the resource will eager load what it needs. While this is more of a lazy reload, it should result in more consistent behavior since no cached results will remain from the initial load.
342 343 344 345 346 347 348 349 350 351 |
# File 'lib/dm-core/resource.rb', line 342 def reload if key reset_key clear_subjects end self.persistence_state = persistence_state.rollback self end |
- (Repository) repository
Repository this resource belongs to in the context of this collection or of the resource's class.
103 104 105 106 |
# File 'lib/dm-core/resource.rb', line 103 def repository # only set @_repository explicitly when persisted defined?(@_repository) ? @_repository : model.repository end |
- (Boolean) save
Save the instance and loaded, dirty associations to the data-store
389 390 391 392 393 394 |
# File 'lib/dm-core/resource.rb', line 389 def save assert_not_destroyed(:save) retval = _save assert_save_successful(:save, retval) retval end |
- (Boolean) save!
Save the instance and loaded, dirty associations to the data-store, bypassing hooks
402 403 404 405 406 407 |
# File 'lib/dm-core/resource.rb', line 402 def save! assert_not_destroyed(:save!) retval = _save(false) assert_save_successful(:save!, retval) retval end |
- (Boolean) saved?
Checks if this Resource instance is saved
147 148 149 |
# File 'lib/dm-core/resource.rb', line 147 def saved? persistence_state.kind_of?(PersistenceState::Persisted) end |
- (Boolean) update(attributes)
Updates attributes and saves this Resource instance
362 363 364 365 366 |
# File 'lib/dm-core/resource.rb', line 362 def update(attributes) assert_update_clean_only(:update) self.attributes = attributes save end |
- (Boolean) update!(attributes)
Updates attributes and saves this Resource instance, bypassing hooks
377 378 379 380 381 |
# File 'lib/dm-core/resource.rb', line 377 def update!(attributes) assert_update_clean_only(:update!) self.attributes = attributes save! end |
- (Object) update_attributes(attributes = {}, *allowed)
Deprecated API for updating attributes and saving Resource
41 42 43 |
# File 'lib/dm-core/resource.rb', line 41 def update_attributes(attributes = {}, *allowed) raise "#{model}#update_attributes is deprecated, use #{model}#update instead (#{caller.first})" end |