My name is Chris Grigg, one of the project’s maintainers, and in this post, I’ll introduce you to some of 3.0’s new and interesting features.

(gem:Neo4jrb)-[:supports]->( PaaS:Heroku)

While Neo4j.rb 2.3 was extremely powerful, its requirement of using JRuby limited deployment options, to say nothing of the complications involved in testing and gem compatibility. 3.0 makes this a thing of the past, with support for Neo4j REST Server using Ruby MRI. If you prefer JRuby and the embedded database, that is still supported; switching between the two involves changing a few simple lines in your application’s config but otherwise, none of your app’s code will have to change. Thanks to this, deploying to the PaaS of your choice is finally possible.

Revolutionary Cypher DSL

Every part of the gem has been overhauled to provide a better combination of ActiveRecord-like syntax and increased power when compared to version 2.3. Nowhere is this more evident than in the new Cypher query DSL, referred to within the gem as QueryProxy. Let’s take a look at a few examples.

Imagine a graph of objects related to college class scheduling. It includes nodes for students, teachers, and lessons, each with corresponding models of the same names and associations between them. Using QueryProxy, matches that would be very complex in SQL and maybe even a little long in Cypher are generated easily with Ruby.

Assuming “student” is a Student node, we can see all of their lessons with one easy query, as any Rails user would expect:

student.lessons

But what if you want to find all of the teachers of all of their lessons? You can chain the Lesson model’s “teachers” association and the server will perform a single Cypher match to generate the response:

student.lessons.teachers

How about finding all of the lessons taught by teachers, age 43? Assuming an “age” property on Teacher, that’s just as easy.

student.lessons(:lesson). teachers.where(age: 43).pluck(:lesson)

Matching relationship properties couldn’t be easier. Want to know all young teachers, age less than 30, who have students in lessons with grades of A+? Chain associations on class methods, call “where” and specify the lesson relationship, and then tell it to give you back the matching teachers!

Teacher.as(:t).where(“t.age < 30”).lessons.students(: student, :lesson_rel).where(“lesson_ rel.grade: ‘A+’”).pluck(:t)

# generates the impressive Cypher:

# MATCH (t:`Teacher`), (lesson:`Lesson`),

(t)-[rel1:`lessons`]->(lesson),

(lesson)<-[lesson_rel:`lessons`]- (student:`Student`)

WHERE t.age < 30 AND lesson_rel.grade = ‘A+’