Wednesday, December 31, 2008

CouchDB Ruby Libraries

This is a quick list of CouchDB Ruby libraries. Need to connect Ruby to CouchDB? Try one of these!

  1. CouchRest - hosted at GitHub, this library by Chris Anderson (jchris), has a low level component and a high level component.
  2. RelaxDB - also hosted at GitHub, this library provides a base class that your models will extend (similar to the high level component provided by CouchRest.) RelaxDB adds pagination support as well as has_many and belongs_to relationship support.
  3. CouchObject - this library is unique because it is implemented as a module, to be included in your model class. This library also has both low level and high level components.
  4. Basic Model - from topfunky, this library was featured in the PeepCode CouchDB episode. Your model classes extend BasicModel.
  5. ActiveCouch - tries to look like ActiveRecord. Supporting a simple find method to query views. Views are defined as Ruby classes, and loaded via rake tasks.
  6. CouchFoo - attempts to replication ActiveRecord look and feel. Newer than the rest of the libraries, so takes lessons learned from all other Ruby libraries.


I've personally used CouchRest, but only its low level components.

For much more in depth analysis of many of these libraries, a little place of calm has a great eight part series on writing Ruby on Rails applications with CouchDB which covers ActiveCouch, RelaxDB, and Basic Model.

Monday, December 29, 2008

Reasons Why CouchDB Is Exciting

I've been playing with CouchDB lately, and having a good time getting out of the relational database mindset. I'm not against relational databases, but I do think the time has come to stop thinking they are the only way to store and process data.

There are a few reasons why I think CouchDB is exciting.

  1. Arbitrary JSON document storage. I like this feature not so much because I'm not required to design a rigid schema, but because it implies that I can store arbitrarily complex and deeply nested data structures. This clears the way for easily storing an object graph without the pains of going through the pains of decomposing into a relational schema.
  2. Incremental view rebuilds. This is a killer feature for me, because it implies that a small change in the data does not invalidate the entire view.
  3. Keys can be complex objects. In other words, you can now use an array or hash as a key in a view. For example, a key can be [2008, 01, 12] which represents a date. Not only is this more flexible, but it lends itself to some very useful query methods. For example, you can query for a range of keys just on the first part of the array.

Friday, December 26, 2008

Multi Model Forms With Rails

Ruby on Rails still doesn't have a good story to tell with regard to multi-model forms. Multi-model forms are HTML forms that have fields from more than one model, which the user edits and submits as one. Rails should take this single collection of fields, split it up into multiple models, and create, edit, or delete as necessary. Unfortunately, this still requires quite a bit of work.

I've collected a set of links that may help those that are new handle multiple models in HTML forms with Rails. None of these are the "official" answer to this complex question. However, it appears that Rails core will one day have an out-of-the-box solution to this. Read on.

Ryan Bates, of Railscasts fame, has probably the best known solution to this problem. He suggests Complex Forms Part 1, Complex Forms Part 2, and Complex Forms Part 3. However, as even he mentions, it doesn't work with Rails 2. Refer to these screencasts, and their sometimes useful comments, as background study.

Ryan offers an alternative for Rails 2 and above. He extended his original screencasts, fixed them for Rails 2, and published them in the Advanced Rails Recipes book, published by the Pragmatic Programmers. You'll want to check out Recipe 13, titled "Handle Multiple Models in One Form" (but you really want the whole book, lots of little gems in there).

An alternative to Ryan's methods can be found at attribute_fu, and Rails plugin by James Golick. attribute_fu is similar to Ryan Bates' code, however it's packaged as a plugin for easy install and use, and uses more conventions to cut down on code. Complete with form helpers and extensions to has_many, you should try this plugin. I don't know if it works with deeply nested models, though.

In July of 2008, there was a glimmer of hope that the Rails core was going to get a blessed solution to this problem. Ryan Daigle, or Ryan's Scraps, reported that Nested Model Mass Assignment was added into Rails! However, it was pulled by the core team because they felt it wasn't ready for prime time. There was a lot of discussion about if and when Rails would have nested model mass assignment. Hopefully it will arrive after 2.2. This is a good discussion and links to other plugins or proposals to handle this tricky problem.

Ryan Bates followed the debate and collected and summarized the various different methods and proposals to handle nested model and nested forms with Rails.

I, for one, will be trying attribute_fu. I've used the Advanced Rails Recipes solution, which certainly works. However, it always felt like too much work for me.

Update: it seems that I wrote about handling collections of models with Rails back in 2007.

Thursday, December 18, 2008

Force HTTP GET for Ext JS DataGrid and Store and JsonReader

I work with ExtJS a lot, and have had great luck with it. We use the layouts, DataGrid, and most of the included widgets.

One thing that has always struck me as odd is the Store (the class responsible for fetching and exposing the data) defaults to a HTTP POST when retrieving data. I think that any retrieval of data from an HTTP end point should be GET, to take advantage of caching and the simple fact that the operation is idempotent.

If you want to force a HTTP GET method to be used when retrieving data with an Ext JS Store (for instance, when retrieving JSON data), here's the Javascript code:

var proxy = new Ext.data.HttpProxy({
url: '/foos.json',
method: 'GET'
});

var store = new Ext.data.Store({
remoteSort: true,
proxy: proxy,
sortInfo: {field: 'id', direction:'desc'},
reader: new Ext.data.JsonReader({
fields: [{name:'id', type:'number'},
{name:"created_at", type: 'date', dateFormat: Date.patterns.XmlSchema},
"category_value",
"sub_category_value",
"created_by_login",
"involved_people_count",
"involved_objects_count",
"percent_complete"],
totalProperty: 'totalRecords',
root: 'records'          
})
});


Notice the external HttpProxy which defines the URI that returns the JSON data as well as the HTTP method. Pass this HttpProxy to the Store and you'll be using GET!

Tuesday, December 16, 2008

Blog Now Hosted At Wordpress.com, Redirects All Setup, Crossing Fingers

I moved this blog to http://blog.semergence.com which is now hosted on wordpress.com.  I just didn't feel the need to continue to host my own installation of wordpress.org, which was always out of date anyway.  Plus, everything else in my life is either rented or a service, so why not my blog?

I told Apache to redirect everything from www.semergence.com that is NOT a file over to blog.semergence.com.  Here's how I did it:

RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^/(.*)$ http://blog.semergence.com%{REQUEST_URI} [R=permanent,QSA,L]


Hopefully your feed reader respects the redirects! And thanks for following!