January72011

My personal holy blog-publishing grail

I’ve discovered the blogging CMS system I’ve been wanting for a very, very long time. I tried to create something simple with my Fikus project, but I see now that I kind of missed the point. I was focused too much on building a web-enabled admin and editor for my content that I forgot to think about what would be the best way to actually deal with blog content.

Blog content should be easy to edit. It should be in a familiar markup language to the author. It should be able to be backed up, easily placed into templates that are editable by technical and semi-technical people alike. It should be organized logically, and you should be able to create RSS feeds easily. Editing the content should be as easy as firing up the content creator’s favorite text editor and going from there.

Notice that I didn’t say anything about a “database”. To me, blog content is just a collection of documents, and not particularly worthy of being considered relational data. Sure, documents may related to one another, but by and large blogs consist of singular posts organized by dates, categories, or tags.

The astute members of the Ruby community may see where this is heading. If you don’t already know, Tom Preston-Werner’s jekyll project fits the requirements I outlined above perfectly.

Your content is organized as a series of text files in either markdown, textile, or html format. You can add some YAML front-matter to the beginning of the document to serve as metadata, describing the title, any permalinks, categories, tags, etc. Running jekyll actually combines your data with layouts (using liquid for templating), and generates static files. There’s also a rack-jekyll gem if you want to deploy the site and run it as a rack application if you don’t want to stick with the static files (or if you have a read-only filesystem in the case of deploying to Heroku).

I’m working on converting over my one remaining Wordpress blog over to jekyll now. Then I can totally uninstall PHP and be done with it! From there I’m going to work on figuring out neat ways of handling social network notifications for Twitter and Facebook, then convert a Tumblr blog or two. I encourage you to check out jekyll if you need something simple, quick, and fun.

October82010
October12010

An Epiphany of Sorts

Over the past year I’ve been a fan of 10gen’s document-oriented database MongoDB. It is most definitely web scale, providing developers with the tools to easily store and retrieve data. It makes a certain amount of sense for a lot of common use cases.

However, I’m finding more and more that people are using it almost exactly like a relational database. Instead of relying on learning embedded documents, map/reduce queries, and the other great things MongoDB provides, people are utilizing ORM-like wrappers for the database making it look exactly like ActiveRecord. So you end up with something that looks and feels just like a MySQL database without the problem of defining schemas and running migrations.

I’m just as guilty at this since I use MongoMapper in a lot of my projects. It’s very popular, powerful, and well-supported. I’ll admit that I like it. Even frameworks like Padrino support it out of the gates. With MongoMapper you can utilize things such as Embedded documents and work with the underlying Mongo driver for ruby and write some very optimal code. However, with this tool it is very easy to fall into the pattern of writing ActiveRecord-like models instead.

Is this a bad thing?

It’s not necessarily bad, but it isn’t the best practices for a document databases. And it most certainly promotes thinking of your data in a more relational manner, which clashes with the underlying design and purpose of MongoDB. To remedy this, I am going to start utilizing a different library more often to help me think of my documents in a more documented-oriented manner. I’m going to start using Candy.

Mmm… Candy…

Candy is a very thin wrapper to the Mongo driver that provides mixins to plain Ruby classes. This gives your classes the magic to atomically and immediately persist your data to MongoDB. Here’s an example:

# Note the lack of defining "keys". Candy uses method_missing
class MagicBlogPost
  include Candy::Piece
end

post = MagicBlogPost.new
post.author = 'Tim Gourley' # New object created and saved. Who needs a .save method?

So yes, you end up with a class with dot-methods that looks a lot like what you get with MongoMapper. But you don’t set up relations, since relations are meaningless in MongoDB. Instead you work with embedded documents (by just using hashes, which makes perfect sense). You don’t have a save method since changes are committed atomically. You don’t even have a find method. Instead you use class methods on your Candy::Piece class, like MagicBlogPost.title(‘Some Article’) or using the more familiar finder methods defined by the Mongo ruby driver, MagicBlogPost.first(‘_id’ => 12345).

There are a lot of advanced things you can do with Candy, but it also helps you keep in line with thinking of your data in terms of a document model instead of as a relational model. A side benefit is that it requires the use of ruby 1.9, which is, in my opinion, a good thing. Let’s start moving off the old and busted ruby 1.8 and onto bigger and better things!

September282010

Continuous Integration Testing with Cerberus and RVM

Many agile developers are in the habit of writing tests for their code. If not taking advantage of test-driven development or behavior-driven design, you are at least writing a few unit tests here and there to make sure key parts of your code are working as intended instead of just working as coded.

One way to help streamline your development process is to introduce continuous integration into your project. This allows you to continuously run your tests, which works better with frequent, smaller commits to your source control. The idea is to reduce the number of errors introduced into your source code, notify the development team on failures, and reduce the time it takes to ship your code.

The workflow looks like this: you write your tests and your code and commit the code to your source control repository. Then a server designated as a CI build server checks for new commits. When it finds one, it updates its copy of the code, runs any building necessary in the case of software needing compilation, then it runs the tests. After the tests are run, the CI software typically sends out notifications about success or failure.

There’s an easy-to-setup gem serving as a basic CI server for ruby, called Cerberus. Installation is as simple as a “gem install cerberus”. It’s a great bit of code because it can be used on any ruby application utilizing rake, so you aren’t limited to just being able to build and test Ruby on Rails applications. This is a boon for me since I write a lot of command-line ruby tools, Sinatra and Padrino applications, and various ruby gems. Testing these with CI in mind is easy with Cerberus.

I also use RVM on my systems to manage ruby versions and gemsets. Cerberus works well with RVM with minimal fuss.

To get started, let’s look at my ruby project rubyspell. It’s an in-progress pure-ruby spell checker and suggestion engine. To get it running under CI, I went to my CI box, and typed in the following:

rvm gemset use global
gem install cerberus
vi ~/.cerberus/config.yml

NOTE: As of this writing this installs some parts of Rails 2.3.9 and throws an error due to a bug in actionpack 2.3.9. To solve this myself I just moved down to version 2.3.5 of those gems.

You only have to edit the ~/.cerberus/config.yml file once. Read the file for directions or check out the Cerberus documentation.

cd ~/ci   # The location of the projects being watched by CI
git clone git://github.com/bratta/rubyspell.git
rvm gemset create rubyspell
rvm gemset use rubyspell
cd rubyspell/
bundle install
cerberus add ~/ci/rubyspell APPLICATION_NAME=rubyspell RECIPIENTS=email@domain.com

Now the project is added. There is one more file to edit, which contains specific information about the project. Edit the file ~/.cerberus/config/rubyspell.yml and add this to the bottom:

builder:
  ruby: 
    task: /usr/local/bin/rvm 1.8.7@rubyspell rake spec

That tells Cerberus to use rvm and the specific gemset to execute rake for building the specs. Once you save that, all you have to do is run cerberus:

cerberus buildall

Add that command to cron to run regularly and you have a full-blown CI setup for generic ruby applications!

11AM

Marching Toward the Ideal Ruby Setup

In my local development I am a huge fan of utilizing Wayne E. Seguin’s amazing project RVM to manage ruby installs. This allows me to play with different versions of ruby, different ruby implementations, and more importantly (to me): manage gemsets for my projects.

Gemsets create a sandbox of ruby gems so that you can deal with what your application is expecting and not have to worry about polluting your gem space or dealing with version dependency issues. Along with the gem bundler, dealing with dependencies has become a lot easier.

RVM In Production

What about dealing with RVM in production? By default, rvm installs rubies under your user account, and gems in the gemsets are installed as you instead of root. What if you want the power of managing ruby and gemsets on a system level, so multiple accounts can take advantage of rvm and defined gemsets?

Significant work has gone into making this a lot easier. It’s now a somewhat simple matter:

Now you should have a rock-solid RVM deployment in production.

Page 1 of 1