Camping.goes :Camping

Eric Mill

Many in the Rails community have at least heard of Camping, a microframework by why the lucky stiff. It was only recently that I discovered that it is genuinely useful, even inspiring, for small applications.

I’m currently at work on a tiny application called Rubedo, which offers a tiny Icecast source client, with an also-tiny web front-end. I’m writing it in Ruby, and so I began to do the front-end in Rails, just to get it working, and this was fine. But this application is small—in its entire life I can’t see it having more than 2 models, and right now it only has 1. Since I’m a RESTful man, the same applies to controllers. Furthermore, this app needs to be light and portable, and looking at it from that perspective, Rails is an atom bomb. I feel strongly about the dropping of the atomic bomb on Hiroshima and Nagasaki, so when a coworker mentioned that this might be a good excuse to try out Camping, I suspected this could be a good fit.

So what is Camping, and why is it so great?

The driving idea behind Camping, as translated from why’s beautiful hummingbird language, is to have your entire MVC application in one file. Failing that, in as few files as possible. First, I’ll give a small code example, stolen right from why. Then, bullet points.

require 'camping'

Camping.goes :Blog

module Blog::Models
  class Post < Base; belongs_to :user; end
  class Comment < Base; belongs_to :user; end
  class User < Base; end
end

module Blog::Controllers
  class Index < R '/'
    def get
      @posts = Post.find :all
      render :index
    end
  end
end

module Blog::Views
  def layout
    html do
      body do
        self << yield
      end
    end
  end

  def index
    for post in @posts
      h1 post.title
    end
  end
end
  • For models, Camping uses ActiveRecord, so your model code is nearly identical to what it would be in Rails.
  • For views, Camping uses Markaby, so views are written entirely in Ruby and frighteningly compact. As you can see, there’s layouts, and don’t worry, there’s also partials.
  • For controllers, Camping uses carefully calculated insanity to intermingle your controllers and routes. This is certainly the most novel part of Camping and the aspect that most differs from Rails, so best practices with it are currently up in the air for me. It’s a land of experimentation.
  • SQLite is the database backend. SQLite satisfies both halves of its name extremely well, and doesn’t require any user authentication or background server process. You should think about using SQLite all the time, including right now.
  • It runs by typing camping blog.rb. You might also use -d blog.db as a parameter to specify the DB file. Then, visit http://localhost:3301 in your browser.

But wait. Routes??

Your controller class inherits from an anonymous class constructed by calling R with a regular expression. So, to make a more nimble route, like to fetch and display a Post by id:

class Posts < R '/posts/(\d+)'
  def get(id)
    @post = Post.find id
    render :post
  end
end

But wait. Javascript?? CSS??

Assuming it’s as simple as your application is, just include it with the rest. Yes:

class Stylesheet < R '/blog.css'
  def get
    @headers['Content-Type'] = 'text/css'
    "body {fist: face}"
  end
end
# in your view
link :href => R(Stylesheet), :rel => 'stylesheet', :type => 'text/css'

But wait. time_ago_in_words??

I couldn’t live without that function either. But you can just include in stuff like that, you know. It’s your app, your dependencies. Like so:

require 'action_view/helpers/date_helper.rb'
module Blog
  include ActionView::Helpers::DateHelper
end

I have absolutely no problem working like this. I don’t foresee my application, even with an upcoming User model and account system, growing beyond the point where I will get antsy about staying in Camping. Having my whole app in front of me while I work is a surprisingly gratifying experience. Working on it feels more like sculpting a statue, or rubbing a weak, newly born mouseling into life.

I was attracted to Rails by its simplicity and how much you could do in a small amount of code. In fact, it seriously eroded my respect in the PHP and Java languages, and frameworks based off of them. After making the decision to build my radio frontend in Camping, and working in it for a week, I feel almost the same degree of attraction. With it does not come any loss of respect for Rails, as Camping just isn’t appropriate for applications above a certain low bar of complexity. It would be only a step or two above trivial to port an application outgrowing its Camping gear into a full Rails application. I think that you would remember the experience fondly.

Yet you may surprise yourself by how complex your code can get, while still being reducible to something good-looking in a Camping jacket. I’ve been steadily adding more features to my application, and after each one follows a brief inner (and outer) struggle to make it work cheaply, tersely, and elegantly. The culture of Camping demands this, and I’m a better person for it.

Insightfully, why created other, more realistic examples of Camping that helped me a great deal in realizing more of Camping’s power. Look over them, maybe even download and run them, to see it at work. Remember though, that Camping, in the end, only attempts to fulfill one overarching and all consuming purpose:

''