Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lazy association creation #871

Merged
merged 14 commits into from
Jul 17, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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