Using Neo4j with Rails 3.2
Neo4j is a NoSQL graph database written in Java. This means that you work with nodes and relationships rather than fixed tables with a schema. Nodes can easily be mapped to Ruby object and relationships seen as references to other objects. This article will show how to utilize Neo4j to build a simple blog application. While this is not a typical application for a graph database it will show how the database can be used in conjunction with Rails.
Prerequisites
The neo4j gem we will be using in this article requires JRuby. If you are using RVM you can install JRuby by typing rvm install jruby. Make sure you have at least JRuby 1.6.2 installed, otherwise Rails will not work properly.
You can then switch to JRuby by using rvm use:
rvm use jruby
To check if everything worked as expected type ruby -v which should return a message like the following:
$ ruby -v jruby 1.6.7.2 (ruby-1.8.7-p357) (2012-05-01 26e08ba) (Java HotSpot(TM) 64-Bit Server VM 1.7.0_05) [linux-amd64-java]
As you can see, JRuby 1.6 is compatible with Ruby 1.8.7. If you want to make use of the latest features in Ruby 1.9 you need to upgrade to JRuby 1.7 which is, at the time of this writing only available as a preview version.
Generate a Rails Application
Now that everything is set up we can create a new Rails project which we will name 'neo_blog'.
gem install rails rails new neo_blog -m http://andreasronge.github.com/rails3.rb -O cd neo_blog bundle
Note: The -O option skips ActiveRecord which we do not need as all functionality for database handling is provided by the neo4j gem.
Creating a blog
We can now use the standard generators of Rails. For a blog application we will need a Post model, a controller and views: A perfect job for the scaffold generator.
rails generate scaffold Post title description content:text published_at:date
This creates several files. The most interesting is the new post model which inherits from Neo4j::Rails::Model. Also note that there are no migration you have to run as Neo4j is schema-less.
class Post < Neo4j::Rails::Model property :title, :type => String property :description, :type => String property :content, :type => String property :published_at, :type => Date end
We should then configure the routes to default to the post controller and delete public/index.html
root :to => 'posts#index'
Adding comments
A blog certainly cannot live without users being able to comment on your posts. We need to add another resource to our project:
rails generate scaffold comment author email content:text
We now have a comment model that we need to associate with our post model. Neo4j provides Neo4j::Rails::Relationship to handle relationships between Neo4j nodes. Neo4j::Rails::Relationship is ActiveModel compatible and implements some ActiveRecord methods, which means you can run validations on it.
Relationships are handled a bit differently than in ActiveRecord. The has_n and has_one class methods generate convenience methods for creating and traversing nodes. However they should not be confused with has_many or has_one! Both has_n and has_one assume relationships to the same class and not to different classes.
As we want to create a relationship from Post to Comment we need to specifically tell Neo4j to create the relationship from posts to comments. The .to methods accepts a class as parameter and defines which class is referenced.
class Post < Neo4j::Rails::Model has_n(:comments).to(Comment) end
With that line in the post model we can easily add new comments to a post. You can try the following on the rails console (rails c)
p = Post.first c = Comment.create(:content => "Nice post!") p.comments << c
Now in order to associate comments to a post we need to change the create action of the comments controller.
def create @post = Post.find(params[:id]) @comment = @post.comments.build(params[:comment]) [..] end
From there you can go ahead an customize the views and CSS to style the blog. JetStrap, a recently released interface-builder for Twitter Bootstrap, makes it easy to create good looking web interfaces. Also have a look at the Github Project of the blog we build here.
Viewing the Neo4j admin web interface
Neo4j comes with a nice web interface which allows you to query the database and browse through the graph. The neo4j-admin gem will start the web interface on port 7474 once your app is started.
gem 'neo4j-admin', group: :development
Note that I added the gem to the development group, so that it will not start in production. When you now restart your app and access http://localhost:7474 on your browser you will see the Neo4j web interface.
Conclusions
The neo4j gem easily allows you to replace ActiveRecord and use Neo4j as a fast graph-based database backend. The blog application shown in this article does certainly not show a typical use case for graph databases where you store highly interconnected data, but serves as an entry point for further work with Neo4j. There are many ways in which the blog application could be extended to make use of the features that a graph database has to offer, some of which will be discussed in a later article.
Andreas Ronge, the author of the Neo4j gem, has developed a well-tested and feature rich gem which is easy to use. The documentation is not always up to date, but there are enough resources available to help with that.
Other Resources
There are many other resources available that provide additional guidance:
- Neo4j 2.x Documentation
- Neo4j 1.3.1 Documentation
- Paperclip for Neo4j
- Carrierwave for Neo4j
- Devise for Neo4j (only works with Devise 1.x)
- JetStrap, a bootstrap building tool
The gems listed are a little bit dated and require some work to get them set up.




Comments
Great article !
Notice that when using
has_nandhas_oneyou can have relationships to any class. The only limitation is that Rails sometimes needs know it when creating new nodes (e.g usingaccepts_nested_attributes_for).The documentation should be rather up to date. I've moved the docs to github wiki, e.g.
Neo4j::Persistence
A few issues I had that might help anyone else following this tutorial:
When generating the application, the template referenced by the -m option didn't seem to work for me. I'm not terribly familiar with these templates, but doing a little legwork, I noticed that http://andreasronge.github.com/rails3.rb is a one-liner that pulls in http://andreasronge.github.com/default.rb. Most of default.rb didn't work for me. The gemfile substitutions didn't do anything and the 'require' additions to config/application.rb didn't seem to work. I was able to figure out the intent pretty easily and add them, though.
Even after that, I ran into issues with the version of neo4j when I tried to run the scaffolding for the Post model. It just failed spectacularly, and rather than try to figure out why, I lazily started by just looking for a newer version of neo4j than 1.3.1. It turns out there is! (2.2.3, as of the time of this comment), and updating my Gemfile with that made things work.
That's as far as I've gotten for now, and all the time I'll have today to work on it. When I pick it back up, I'll post other notes if I run into more issues.
Thanks for the tutorial!
The admin console part also didn't work for me at first. I went and found the readme for the gem project on github (https://github.com/andreasronge/neo4j-admin) and noticed that config/application has to contain the following line as well:
require 'neo4j-admin/railtie'
After adding this and restarting the app, things work as described
Mark, I found that the template at andreasronge.github.com/neo4j/rails.rb worked for me.
This is described at andreasronge.github.com/neo4j/ although I first found it mentioned in a very useful google groups discussion at https://groups.google.com/forum/?fromgroups=#!searchin/neo4jrb/devise/neo4jrb/WPCZ5C_gVbE/GPuFvbcS9LQJ where Chris F. shows how to get devise-neo4j working (authentication). Very cool.
Anyway, the rails command that worked for me was:
Following on from Marks first comment, I found this command worked:
This is referenced from Andreas page at http://andreasronge.github.com/neo4j/
I've found that the code example has an error. I cloned the project at github.com/geekproject/neo_blog, did a bundle update (which moved the neo4j.rb gem from 2.0.1 to 2.2.3 and rails from 3.2.8 to 3.2.11). But when trying the app out, I cannot add comments to the blog, because line 43 of the comments_controller (create method) returns nil from the call:
Looking at the partials I am not able to see how params[:id] was supposed to be set. The comments/_form partial is called from posts/show.html.erb using a line like:
Since this is in the posts/show view, I assume rails is supposed to magically set the params[:id], but the params I get in the comments creation contain only the comments form fields:
I must assume the original code worked fine with older gems, so what could have changed (or is there a bug in the example code on github?)
And after adding the admin console, if I try view the graph view in that, I get the error:
Hi Craig,
paramsis a hash automatically available in Rails. See Rails Parameters.I'll look into the other errors.
Hello!
I am trying to create my first application with use of Ruby on Rails (3.2.13) and Neo4j.
I have a problem with a person:) I have created Person model class and People Controller (with use of Scaffolding). I can create nodes of Person (I can see it in Neoclipse), but when I try to find a person with given name, RoR gives me the answer, that there is no such a person.
I have tested it with other classes, like place, device etc. and it works perfectly.
May it be a problem with different pluralization of a word “person”? Do you know how to fix this problem?