Originally posted on the Neo4j.rb Blog
Just three months since releasing 3.0, we’re proud to have Neo4j.rb 4.1, and Neo4j-core 4.0 released to the world. Are you excited?
We’re stoked. Get it by changing your gemfile to
gem 'neo4j', '~> 4.1.0'
or if you just have
gem 'neo4j'
, a
bundle update neo4j
will do it. Please see
this article, which outlines the potentially breaking API changes related to relationship types.
What happened to 4.0?
Why jump straight to 4.1? Well, we didn’t really, we just released 4.0 and 4.1 within 40 minutes of each other. It’s pretty simple, really:
- 4.0.0 is 4.0.0.rc.4 (released Dec 22, 2014) with the gemspec set to require neo4j-core 4.0.0, which has no changes we expect to cause problems but many important performance fixes.
- 4.1.0 includes all of the commits made since Dec 22.
This was done because we want users to trust that if rc4 worked for them, 4.0.0 can be trusted. We did not think another release candidate was necessary. 4.1.0 was born.
What Changed Since 3.x?
Full Support for Neo4j 2.2
This includes the new basic authentication option. A new class in Neo4j-core lets you work directly with the authentication REST endpoint. There are new rake tasks, too:
neo4j:enable_authentication
,
neo4j:disable_authentication
, and
neo4j:change_password
.
neo4j:install
has been updated to disable basic auth automatically, as this is intended for low-security dev environments.
We are running all of our tests against 2.2.0-M01 right now and will move to 2.2.0 when it is released. You can see our CI at
https://travis-ci.org/neo4jrb/neo4j, where you’ll notice we’re testing against Ruby 2.2.0, 1.9.3, and JRuby 1.7.16.
SPEED
Almost everything you do will be faster. Our benchmarks show performance improvements of more than 2x on most repeat queries. This is mostly thanks to changes in Neo4j-core. Read about it at
here. This will be very noticeable in environments where your database and web servers are on two different machines.
“_classname” properties are no longer added (Neo4j 2.1.5+)
_classname
, one of our least favorite (but totally necessary) features of 3.x, is not needed anymore as long as you are running Neo4j 2.1.5 or greater, which you should be. See
https://neo4jrb.io/blog/2014/12/23/theroadto_4-0.html for more detail than you’ll ever want.
This wiki pageoutlines the implications of this.
Better automatic relationship types
If you use automatic relationship typing,
has_many :out, :students
, 4.x will now make the relationship type
STUDENTS
instead of
#students
. This is to bring it in line with Neo4j relationship naming best practices. It can be configured for legacy purposes and taste, see
this documentation. The wiki page linked above also spells this out quite a bit.
ActiveRel: automatic matching of returned relationships to models, no more explicit “type” required
If you create an ActiveRel class called
EnrolledIn
, it will automatically set the type to
ENROLLED_IN
— you do not need to explicitly say
type 'ENROLLED_IN'
. It respects whatever options you set when configuration automatic relationship types as described in the documentation above.
As a bonus, if you create a relationship from an association, say
student.lessons << math
and your Student model is set with
has_many :out, :lessons, type: 'ENROLLED_IN'
, the
rel_class
option is unnecessary. This is all related to the death of
_classname
.
The flipside of this is that if your relationship model’s name does not match the relationship type, you should enable
eager_load
in your Rails environment’s config. See docs for more details. Once more, see
this page for a clear walkthrough of these implications.
All create, update, and destroy actions are wrapped in transactions
Thanks to performance improvements in core, we can do this and things are still much faster than 3.x. See
this blog post for info.
Scopes are more powerful
You can now chain scopes and methods to QueryProxy objects. If
top_students
is defined as a scope or method in
Lesson
that finds students with certain grades,
Student.all.where(age: 18).lessons.top_students
will now work. See
this spec for examples, with more documentation to come.
Our code is cleaner and more consistent
Brian spent a few days attacking both gems with Rubocop and his keen eye for detail. Rubocop compliance is now a required part of our test process. We have some strong feelings about this; see
Brian’s post on the topic.
New association option: dependent
Similar to ActiveRecord,
dependent: :delete
and friends are now options on associations in ActiveNode. We have some uniquely graphy options, too. See blog post
here.
Association option: unique: true
and ActiveRel class method creates_unique_rel
Using either of these will change the Cypher used to create relationships from
CREATE
to
CREATE UNIQUE
. You can read about that in Neo4j’s
CREATE UNIQUE
documentation.
“OPTIONAL MATCH” and chaining QueryProxy to Core::Query back to QueryProxy
It’s now possible to use Cypher’s OPTIONAL MATCH in QueryProxy instead of plain ole MATCH and transform a
Core::Query
object into a friendlier
QueryProxy
object. A blog or possibly screencast is coming about this but in the meantime, the best places to see these in action are the specs:
optional and
proxy_as. There’s also a
proxy_as_optional
method in Core::Query if you’re looking for more control.
A lot of new QueryProxy instance methods
Things like…
match_to
, for creating a match around a specific node, id, or group of nodes
rels_to
and first_rel_to
, returns all rels or the first rel between a chain and a given node
rel_where
, like where
but for relationships
node_where
, an aliased version of where
to make things a bit more explicit and readable
delete_all
, deletes all matched nodes and rels within Cypher
delete
and destroy
, which destroy relationships matched in Cypher and Ruby, respectively
The
query_proxy_methods_spec.rb
file is easy to read and demonstrates all of these, so it’s a great thing to keep an eye on.
Upgrading an App from 3.x to 4.x
If you have a 3.x app, the upgrade process is relatively simple.
- If you are using automatic relationship naming, meaning you do not use the
type
option in associations, your relationship types will change. Set config.neo4j.transform_rel_type = :legacy
in application.rb
or update your data and modify Cypher queries based on the new automatic names. See this.
- If the above applies to you, note that
transform_rel_type
will also affect ActiveRel’s new automatic relationship naming. You should continue using type
in your models and enable eager_load
in your environment’s config file.
- If you are using ActiveRel and your model names do not match the relationship types (your model is
StudentLesson
and the type is ENROLLED_IN
), enable eager_load
in your environment’s config file.
- If you are using the same relationship type in multiple ActiveRel models, you are reliant on
_classname
. Use the class method set_classname
in your model, continue using type
, and enable eager_load
, as with the other solutions.
This behavior is all described in detail at
this page. Please open an issue or reach out to one of us directly if you need help.
Want to learn more about graph databases? Click below to get your free copy of O’Reilly’s Graph Databases ebook and discover how to use graph technologies for your application today.
Download My Ebook