Skip to content

Commit

Permalink
Merge pull request #871 from neo4jrb/lazy_association_creation
Browse files Browse the repository at this point in the history
Lazy association creation
  • Loading branch information
subvertallchris committed Jul 17, 2015
2 parents 7be1330 + 9e2e588 commit be01fd1
Show file tree
Hide file tree
Showing 28 changed files with 577 additions and 93 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@ This project adheres to [Semantic Versioning](http://semver.org/).

### Fixed
- Added a `before_remove_const` method to clear cached models when Rails `reload!` is called. 5.0.1 included a workaround but this appears to cut to the core of the issue. See https://github.com/neo4jrb/neo4j/pull/855.
- To prevent errors, changing an index to constraint or constraint to index will drop the existing index/constraint before adding the new.
- Fixed `AssociationProxy#method_missing` so it properly raises errors.

### Added
- Added ability to view `model_class` from `Association` class for `rails_admin` Neo4j adapter
- QueryProxy `where` will now look for declared properties matching hash keys. When found, it will send the value through that property's type converter if the type matches the property's unconverted state.
- Improved handling of unpersisted nodes with associations. You can now use `<<` to create associations between unpersisted nodes. A `save` will cascade through unpersisted objects, creating nodes and rels along the way. See https://github.com/neo4jrb/neo4j/pull/871

## [5.0.4] - 2015-07-17

Expand Down
44 changes: 44 additions & 0 deletions docs/Querying.rst
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,50 @@ Here we are limiting lessons by the ``start_date`` and ``end_date`` on the relat
student.lessons.where(subject: 'Math').rel_where(grade: 85)
Associations and Unpersisted Nodes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

There is some special behavior around association creation when nodes are new and unsaved. Below are a few scenarios and their outcomes.

When both nodes are persisted, associations changes using ``<<`` or ``=`` take place immediately -- no need to call save.

.. code-block:: ruby
student = Student.first
Lesson = Lesson.first
student.lessons << lesson
In that case, the relationship would be created immediately.

When the node on which the association is called is unpersisted, no changes are made to the database until ``save`` is called. Once that happens, a cascading save event will occur.

.. code-block:: ruby
student = Student.new
lesson = Lesson.first || Lesson.new
# This method will not save `student` or change relationships in the database:
student.lessons << lesson
Once we call ``save`` on ``student``, two or three things will happen:

* Since ``student`` is unpersisted, it will be saved
* If ``lesson`` is unpersisted, it will be saved
* Once both nodes are saved, the relationship will be created

This process occurs within a transaction. If any part fails, an error will be raised, the transaction will fail, and no changes will be made to the database.

Finally, if you try to associate an unpersisted node with a persisted node, the unpersisted node will be saved and the relationship will be created immediately:

.. code-block:: ruby
student = Student.first
lesson = Lesson.new
student.lessons << lesson
In the above example, ``lesson`` would be saved and the relationship would be created immediately. There is no need to call ``save`` on ``student``.


Parameters
~~~~~~~~~~

Expand Down
Binary file modified docs/_exts/hidden_code_block.pyc
Binary file not shown.
30 changes: 17 additions & 13 deletions docs/api/Neo4j.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,18 @@ Neo4j

Neo4j/Config

Neo4j/Shared

Neo4j/Neo4jrbError

Neo4j/RecordNotFound

Neo4j/Shared

Neo4j/Railtie



Neo4j/ClassWrapper

Neo4j/Railtie

Neo4j/Paginated

Neo4j/Migration
Expand Down Expand Up @@ -62,16 +62,16 @@ Files

* `lib/neo4j/config.rb:1 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/config.rb#L1>`_

* `lib/neo4j/errors.rb:1 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/errors.rb#L1>`_

* `lib/neo4j/shared.rb:1 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/shared.rb#L1>`_

* `lib/neo4j/errors.rb:1 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/errors.rb#L1>`_
* `lib/neo4j/railtie.rb:4 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/railtie.rb#L4>`_

* `lib/neo4j/version.rb:1 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/version.rb#L1>`_

* `lib/neo4j/wrapper.rb:1 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/wrapper.rb#L1>`_

* `lib/neo4j/railtie.rb:4 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/railtie.rb#L4>`_

* `lib/neo4j/paginated.rb:1 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/paginated.rb#L1>`_

* `lib/neo4j/migration.rb:3 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/migration.rb#L3>`_
Expand All @@ -82,18 +82,18 @@ Files

* `lib/neo4j/type_converters.rb:1 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/type_converters.rb#L1>`_

* `lib/neo4j/active_rel/types.rb:1 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_rel/types.rb#L1>`_

* `lib/neo4j/shared/callbacks.rb:1 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/shared/callbacks.rb#L1>`_

* `lib/neo4j/active_rel/types.rb:1 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_rel/types.rb#L1>`_

* `lib/neo4j/active_node/query.rb:1 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/query.rb#L1>`_

* `lib/neo4j/shared/typecaster.rb:1 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/shared/typecaster.rb#L1>`_

* `lib/neo4j/active_node/labels.rb:1 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/labels.rb#L1>`_

* `lib/neo4j/shared/validations.rb:1 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/shared/validations.rb#L1>`_

* `lib/neo4j/active_node/labels.rb:1 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/labels.rb#L1>`_

* `lib/neo4j/active_rel/callbacks.rb:1 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_rel/callbacks.rb#L1>`_

* `lib/neo4j/active_node/callbacks.rb:1 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/callbacks.rb#L1>`_
Expand All @@ -102,10 +102,12 @@ Files

* `lib/neo4j/active_rel/validations.rb:1 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_rel/validations.rb#L1>`_

* `lib/neo4j/active_node/orm_adapter.rb:3 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/orm_adapter.rb#L3>`_

* `lib/neo4j/active_node/validations.rb:1 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/validations.rb#L1>`_

* `lib/neo4j/active_node/unpersisted.rb:1 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/unpersisted.rb#L1>`_

* `lib/neo4j/active_node/orm_adapter.rb:3 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/orm_adapter.rb#L3>`_

* `lib/neo4j/active_node/query_methods.rb:1 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/query_methods.rb#L1>`_

* `lib/rails/generators/neo4j_generator.rb:5 <https://github.com/neo4jrb/neo4j/blob/master/lib/rails/generators/neo4j_generator.rb#L5>`_
Expand All @@ -122,6 +124,8 @@ Files

* `lib/neo4j/active_node/dependent/query_proxy_methods.rb:1 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/dependent/query_proxy_methods.rb#L1>`_

* `lib/neo4j/active_node/query/query_proxy_unpersisted.rb:1 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/query/query_proxy_unpersisted.rb#L1>`_

* `lib/neo4j/active_node/dependent/association_methods.rb:1 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/dependent/association_methods.rb#L1>`_

* `lib/neo4j/active_node/query/query_proxy_eager_loading.rb:1 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/query/query_proxy_eager_loading.rb#L1>`_
Expand Down
56 changes: 44 additions & 12 deletions docs/api/Neo4j/ActiveNode.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ in a new object of that class.

ActiveNode/Rels

ActiveNode/Scope

ActiveNode/Query

ActiveNode/Scope

ActiveNode/HasN

ActiveNode/Labels
Expand All @@ -41,20 +41,22 @@ in a new object of that class.

ActiveNode/Dependent

ActiveNode/Reflection

ActiveNode/Initialize

ActiveNode/IdProperty

ActiveNode/ClassMethods
ActiveNode/Reflection

ActiveNode/OrmAdapter
ActiveNode/IdProperty

ActiveNode/Validations

ActiveNode/Persistence

ActiveNode/Unpersisted

ActiveNode/ClassMethods

ActiveNode/OrmAdapter

ActiveNode/QueryMethods


Expand Down Expand Up @@ -82,10 +84,10 @@ Files

* `lib/neo4j/active_node/rels.rb:1 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/rels.rb#L1>`_

* `lib/neo4j/active_node/scope.rb:3 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/scope.rb#L3>`_

* `lib/neo4j/active_node/query.rb:2 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/query.rb#L2>`_

* `lib/neo4j/active_node/scope.rb:3 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/scope.rb#L3>`_

* `lib/neo4j/active_node/has_n.rb:1 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/has_n.rb#L1>`_

* `lib/neo4j/active_node/labels.rb:2 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/labels.rb#L2>`_
Expand All @@ -100,12 +102,14 @@ Files

* `lib/neo4j/active_node/id_property.rb:1 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/id_property.rb#L1>`_

* `lib/neo4j/active_node/orm_adapter.rb:4 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/orm_adapter.rb#L4>`_

* `lib/neo4j/active_node/validations.rb:2 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/validations.rb#L2>`_

* `lib/neo4j/active_node/persistence.rb:1 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/persistence.rb#L1>`_

* `lib/neo4j/active_node/unpersisted.rb:2 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/unpersisted.rb#L2>`_

* `lib/neo4j/active_node/orm_adapter.rb:4 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/orm_adapter.rb#L4>`_

* `lib/neo4j/active_node/query_methods.rb:2 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/query_methods.rb#L2>`_

* `lib/neo4j/active_node/has_n/association.rb:4 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/has_n/association.rb#L4>`_
Expand All @@ -120,6 +124,8 @@ Files

* `lib/neo4j/active_node/dependent/query_proxy_methods.rb:2 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/dependent/query_proxy_methods.rb#L2>`_

* `lib/neo4j/active_node/query/query_proxy_unpersisted.rb:2 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/query/query_proxy_unpersisted.rb#L2>`_

* `lib/neo4j/active_node/dependent/association_methods.rb:2 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/dependent/association_methods.rb#L2>`_

* `lib/neo4j/active_node/query/query_proxy_eager_loading.rb:2 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/query/query_proxy_eager_loading.rb#L2>`_
Expand Down Expand Up @@ -671,6 +677,32 @@ Methods



.. _`Neo4j/ActiveNode#pending_associations`:

**#pending_associations**


.. hidden-code-block:: ruby

def pending_associations
@pending_associations ||= {}
end



.. _`Neo4j/ActiveNode#pending_associations?`:

**#pending_associations?**


.. hidden-code-block:: ruby

def pending_associations?
!@pending_associations.blank?
end



.. _`Neo4j/ActiveNode#persisted?`:

**#persisted?**
Expand Down
4 changes: 0 additions & 4 deletions docs/api/Neo4j/ActiveNode/HasN.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,6 @@ HasN







HasN/ClassMethods

HasN/Association
Expand Down
4 changes: 1 addition & 3 deletions docs/api/Neo4j/ActiveNode/HasN/AssociationProxy.rst
Original file line number Diff line number Diff line change
Expand Up @@ -184,13 +184,11 @@ Methods

def method_missing(method_name, *args, &block)
target = target_for_missing_method(method_name)
super if target.nil?
cache_query_proxy_result if !cached? && !target.is_a?(Neo4j::ActiveNode::Query::QueryProxy)

clear_cache_result if target.is_a?(Neo4j::ActiveNode::Query::QueryProxy)

return if target.nil?

target.public_send(method_name, *args, &block)
end
Expand Down
2 changes: 1 addition & 1 deletion docs/api/Neo4j/ActiveNode/HasN/ClassMethods.rst
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ Files



* `lib/neo4j/active_node/has_n.rb:170 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/has_n.rb#L170>`_
* `lib/neo4j/active_node/has_n.rb:158 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/has_n.rb#L158>`_



Expand Down
10 changes: 7 additions & 3 deletions docs/api/Neo4j/ActiveNode/Persistence.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ Persistence





Persistence/ClassMethods


Expand Down Expand Up @@ -119,7 +121,7 @@ Methods
node = _create_node(properties)
init_on_load(node, node.props)
send_props(@relationship_props) if @relationship_props
@relationship_props = nil
@relationship_props = @deferred_nodes = nil
true
end

Expand Down Expand Up @@ -326,8 +328,10 @@ Methods

def save(*)
update_magic_properties
association_proxy_cache.clear
create_or_update
cascade_save do
association_proxy_cache.clear
create_or_update
end
end


Expand Down
3 changes: 1 addition & 2 deletions docs/api/Neo4j/ActiveNode/Persistence/ClassMethods.rst
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Files



* `lib/neo4j/active_node/persistence.rb:69 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/persistence.rb#L69>`_
* `lib/neo4j/active_node/persistence.rb:85 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/persistence.rb#L85>`_



Expand All @@ -68,7 +68,6 @@ Methods

def create(props = {})
association_props = extract_association_attributes!(props) || {}

new(props).tap do |obj|
yield obj if block_given?
obj.save
Expand Down
4 changes: 4 additions & 0 deletions docs/api/Neo4j/ActiveNode/Query.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ Helper methods to return Neo4j::Core::Query objects. A query object can be used

Query/QueryProxyEnumerable

Query/QueryProxyUnpersisted

Query/QueryProxyEagerLoading

Query/QueryProxyFindInBatches
Expand Down Expand Up @@ -54,6 +56,8 @@ Files

* `lib/neo4j/active_node/query/query_proxy_enumerable.rb:3 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/query/query_proxy_enumerable.rb#L3>`_

* `lib/neo4j/active_node/query/query_proxy_unpersisted.rb:3 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/query/query_proxy_unpersisted.rb#L3>`_

* `lib/neo4j/active_node/query/query_proxy_eager_loading.rb:3 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/query/query_proxy_eager_loading.rb#L3>`_

* `lib/neo4j/active_node/query/query_proxy_find_in_batches.rb:3 <https://github.com/neo4jrb/neo4j/blob/master/lib/neo4j/active_node/query/query_proxy_find_in_batches.rb#L3>`_
Expand Down
Loading

0 comments on commit be01fd1

Please sign in to comment.