Persistence¶
Constants¶
Methods¶
- #_create_node
TODO: This does not seem like it should be the responsibility of the node. Creates an unwrapped node in the database.
def _create_node(node_props, labels = labels_for_create) self.class.neo4j_session.create_node(node_props, labels) end
#apply_default_values
def apply_default_values return if self.class.declared_property_defaults.empty? self.class.declared_property_defaults.each_pair do |key, value| self.send("#{key}=", value) if self.send(key).nil? end end
#cache_key
def cache_key if self.new_record? "#{model_cache_key}/new" elsif self.respond_to?(:updated_at) && !self.updated_at.blank? "#{model_cache_key}/#{neo_id}-#{self.updated_at.utc.to_s(:number)}" else "#{model_cache_key}/#{neo_id}" end end
- #concurrent_increment!
Increments concurrently a numeric attribute by a centain amount
def concurrent_increment!(attribute, by = 1) query_node = Neo4j::Session.query.match_nodes(n: neo_id) increment_by_query! query_node, attribute, by end
- #create_model
Creates a model with values matching those of the instance attributes and returns its id.
def create_model node = _create_node(props_for_create) init_on_load(node, node.props) send_props(@relationship_props) if @relationship_props @relationship_props = @deferred_nodes = nil true end
#create_or_update
def create_or_update # since the same model can be created or updated twice from a relationship we have to have this guard @_create_or_updating = true apply_default_values result = _persisted_obj ? update_model : create_model if result == false Neo4j::Transaction.current.failure if Neo4j::Transaction.current false else true end rescue => e Neo4j::Transaction.current.failure if Neo4j::Transaction.current raise e ensure @_create_or_updating = nil end
#destroy
def destroy freeze _persisted_obj && _persisted_obj.del @_deleted = true end
- #destroyed?
Returns +true+ if the object was destroyed.
def destroyed? @_deleted end
#exist?
def exist? _persisted_obj && _persisted_obj.exist? end
#freeze
def freeze @attributes.freeze self end
#frozen?
def frozen? @attributes.frozen? end
- #increment
Increments a numeric attribute by a centain amount
def increment(attribute, by = 1) self[attribute] ||= 0 self[attribute] += by self end
- #increment!
Convenience method to increment numeric attribute and #save at the same time
def increment!(attribute, by = 1) increment(attribute, by).update_attribute(attribute, self[attribute]) end
- #inject_primary_key!
As the name suggests, this inserts the primary key (id property) into the properties hash. The method called here, default_property_values, is a holdover from an earlier version of the gem. It does NOT contain the default values of properties, it contains the Default Property, which we now refer to as the ID Property. It will be deprecated and renamed in a coming refactor.
def inject_primary_key!(converted_props) self.class.default_property_values(self).tap do |destination_props| destination_props.merge!(converted_props) if converted_props.is_a?(Hash) end end
#labels_for_create
def labels_for_create self.class.mapped_label_names end
- #new?
Returns +true+ if the record hasn’t been saved to Neo4j yet.
def new_record? !_persisted_obj end
- #new_record?
Returns +true+ if the record hasn’t been saved to Neo4j yet.
def new_record? !_persisted_obj end
- #persisted?
Returns +true+ if the record is persisted, i.e. it’s not a new record and it was not destroyed
def persisted? !new_record? && !destroyed? end
#props
def props attributes.reject { |_, v| v.nil? }.symbolize_keys end
- #props_for_create
Returns a hash containing: * All properties and values for insertion in the database * A uuid (or equivalent) key and value * Timestamps, if the class is set to include them. Note that the UUID is added to the hash but is not set on the node. The timestamps, by comparison, are set on the node prior to addition in this hash.
def props_for_create inject_timestamps! props_with_defaults = inject_defaults!(props) converted_props = props_for_db(props_with_defaults) return converted_props unless self.class.respond_to?(:default_property_values) inject_primary_key!(converted_props) end
#props_for_persistence
def props_for_persistence _persisted_obj ? props_for_update : props_for_create end
#props_for_update
def props_for_update update_magic_properties changed_props = attributes.select { |k, _| changed_attributes.include?(k) } changed_props.symbolize_keys! inject_defaults!(changed_props) props_for_db(changed_props) end
#reload
def reload return self if new_record? association_proxy_cache.clear if respond_to?(:association_proxy_cache) changed_attributes && changed_attributes.clear unless reload_from_database @_deleted = true freeze end self end
#reload_from_database
def reload_from_database reloaded = self.class.load_entity(neo_id) reloaded ? init_on_reload(reloaded._persisted_obj) : nil end
- #save
Saves the model.
If the model is new a record gets created in the database, otherwise the existing record gets updated. If perform_validation is true validations run. If any of them fail the action is cancelled and save returns false. If the flag is false validations are bypassed altogether. See ActiveRecord::Validations for more information. There’s a series of callbacks associated with save. If any of the before_* callbacks return false the action is cancelled and save returns false.
def save(*) cascade_save do association_proxy_cache.clear create_or_update end end
- #save!
Persist the object to the database. Validations and Callbacks are included by default but validation can be disabled by passing :validate => false to #save! Creates a new transaction.
def save!(*args) save(*args) or fail(RecordInvalidError, self) # rubocop:disable Style/AndOr end
#touch
def touch fail 'Cannot touch on a new record object' unless persisted? update_attribute!(:updated_at, Time.now) if respond_to?(:updated_at=) end
- #update
Updates this resource with all the attributes from the passed-in Hash and requests that the record be saved. If saving fails because the resource is invalid then false will be returned.
def update(attributes) self.attributes = process_attributes(attributes) save end
- #update!
Same as {#update_attributes}, but raises an exception if saving fails.
def update!(attributes) self.attributes = process_attributes(attributes) save! end
- #update_attribute
Convenience method to set attribute and #save at the same time
def update_attribute(attribute, value) send("#{attribute}=", value) self.save end
- #update_attribute!
Convenience method to set attribute and #save! at the same time
def update_attribute!(attribute, value) send("#{attribute}=", value) self.save! end
- #update_attributes
Updates this resource with all the attributes from the passed-in Hash and requests that the record be saved. If saving fails because the resource is invalid then false will be returned.
def update(attributes) self.attributes = process_attributes(attributes) save end
- #update_attributes!
Same as {#update_attributes}, but raises an exception if saving fails.
def update!(attributes) self.attributes = process_attributes(attributes) save! end
#update_model
def update_model return if !changed_attributes || changed_attributes.empty? _persisted_obj.update_props(props_for_update) changed_attributes.clear end