Basic usage of Riak in Rails
OK, you’re convinced that Riak is a great database, now you want to use it in your Rails 3 app. You should really have a look at the advices from Basho, and especially the Riak with Rails slides from Sean Cribbs.
So first, let’s install the rich ruby client for Riak, ripple, built on top of riak-client. Simply add the following lines to your
Gemfile
:
gem 'ripple' #=> riak orm ; installs "riak-client" as a dependency
gem 'excon' #=> faster http
gem 'yajl-ruby' #=> faster json
…and of course run bundle
command.
Then generate your ripple config with:
rails generate ripple
Optionnaly you can configure the config/ripple.yml
file. With the environment I used in my previous article, I had to change the riak server’s port (default is 8098, I had to
change it to 8091, 92 or 93 for my development cluster).
Then generate a first model:
rails generate ripple:model Article title:string content:text
The generated app/models/article.rb
looks like this:
class Article
include Ripple::Document
property :title, String
property :content, String
end
You can optionnaly add timestamps!
if you want to have created_at/updated_at
fields updated automatically by ripple.
You can now test everything runs fine in a rails console
session:
>> Article.all
=> []
>> Article.create(:title => "A shiny title", :content => "Lorem ipsum blah bleh")
=> <Article:Fp1RZWPRDcDLLjDv8aJ0t3p0C5i created_at=2011-04-23 16:25:13 UTC title="A shiny title" content="Lorem ipsum blah bleh" updated_at=2011-04-23 16:25:13 UTC>
Looks ok, but the key isn’t so pretty. After a quick search on google, it appears that this key is auto-generated by Riak if not provided by the client, and it’s pretty easy to define your own key format. I personnaly wanted the creation date and the title in the key:
def key
@key ||= "#{created_at.strftime("%Y%m%d%H%M%S")}-#{title.parameterize}"
end
Now it looks better:
>> reload!
Reloading...
=> true
>> Article.create(:title => "A shiny title", :content => "Lorem ipsum blah bleh")
=> <Article:20110423182948-a-shiny-title created_at=2011-04-23 16:29:48 UTC title="A shiny title" content="Lorem ipsum blah bleh" updated_at=2011-04-23 16:29:48 UTC>
It seems there’s a tiny problem with Article.all
, since it doesn’t contain the newly created item. I’ll ask about that on the riak mailing
list, but it seems Riak client does a bit of caching. If you really need it, reset the cache by hand, it’s ugly but it works:
>> Article.all
=> []
>> Ripple.client.instance_variable_set(:@bucket_cache,nil)
=> nil
>> Article.all
=> [<Article:20110423183635-a-shiny-title created_at=2011-04-23 16:36:35 UTC title="A shiny title" content="Lorem ipsum blah bleh" updated_at=2011-04-23 16:36:35 UTC>]
Now, what about the controller side ? This is where Rails 3 has become a powerful solution, it’s database agnostic. I generated a scaffold with the 7 standard crud actions:
rails generate scaffold Article title:string content:text
It works for 6 of the 7 elementary actions, but I must admit I had a tiny problem with the destroy
action, because of a bug in ActiveModel. It’s
described here with a workaround, so I added those 2
lines in my Article model:
def validation_context=(value); end
def initialize(*args); errors; super(*args); end
I’m not really sure which impact it will have on my validations, but validations and links between objects are for the next article. That’s all for today, hope this article will be useful for some of you!
edit: replaced ‘curb’ gem by ‘excon’