Simple Captcha Released

Posted over 7 years back at Ajax on Rails


Hey guys, finally i have released the captcha plugin for public usage.

Check it out here

WS-* == Windows Services Dash Star?

Posted over 7 years back at Ryan Tomayko's Writings

Tim said it:

WS-*? In the real world, it’s about being able to interoperate with WCF, and while that’s a worthwhile thing, that’s all it’s about. It’s not like HTTP or TCP/IP, truly interoperable frameworks, it’s like DCOM; the piece of Windows’ network-facing surface that Microsoft would like you to code to. For now, anyhow; it’ll be at least as easy as DCOM to walk away from when the embarrassment gets too great.

Holy crap.

Has it really slid this far out of control already? I was thinking the industry could keep to their talking points and rip off a few thousand more clueless IT managers over the next few years but when Gartner gives up on you, it’s a pretty safe bet that your days are numbered.

Engines 1.2 Released

Posted over 7 years back at Rails Engines News

I’ve just pushed the 1.2 release of the engines plugin forward as the official release found by script/plugin. The 1.2 release is compatible with Rails 1.2, and undoubtedly the best release so far. It’s never been easier to make your plugins more powerful, and I’m very happy with some of the new features 1.2 gives, including routes in plugins and a new “best-practise” for sharing migrations.

Engines are dead…

The new 1.2 release also represents a psychological “reboot” for the engines plugin. Thanks to some of the features we managed to contribute to Rails itself, any plugin can be enhanced by the engines plugin. This is the final blow to the unfortunate misunderstanding that “engines are evil”, because there’s literally no such thing as “an engine” anymore. The engines plugin is just a plugin that makes other plugins more powerful.

Below the cut you can read about some of the enhancements that the engines plugin contributes to making sharing code amongst your projects even simpler.

Continue Reading…

The Camping Episode - Ruby on Rails Podcast

Posted over 7 years back at Ruby on Rails Podcast

Three interviews with developers who use why the lucky stiff’s Camping framework.
See also

Refactoring REST: searching for an abstraction

Posted over 7 years back at Luke Redpath - Home

It’s been a while since I blogged. Sorry about that. Needless to say, it’s been a hectic couple of months. Birthdays, Christmas, New Year, a new job; all found their way towards keeping me from that big shiny text-box in Mephisto’s admin interface. For those still waiting for part two of my RSpec tutorial – and I know I’ve said this several times already – it will be coming; I’m just not sure when yet. There are some interesting developments afoot in the world of RSpec and I’ll be waiting until these make it into the next major release before tackling the article.

In this article, I’d like to talk about REST. The world of REST and resources has been a part of the Rails edge for a while now, since the last RailsConf in fact and whilst skeptical at first, I’ve really come around to the concept of RESTful resources. Whilst I still feel that it is not always suitable I’ve found that the best approach is combination of RESTful controllers and RPC-style controllers where necessary. One of the great things about the RESTful approach is that it really brings the idea of good object-oriented design – specifically the idea of objects having a clear focus on a particular task – to Rails controllers. The downside is that normalization of REST-style controllers has led to, in my experience, a lot of repetitive code. And as every good programmer knows, duplication should be hunted down and destroyed whenever possible.

The wonderful world of REST

The RESTful resources concept focusses on seven core actions: index, show, new, create, edit, update and destroy. These actions expose four core behaviours of your ActiveRecord objects through some of the various verbs available in the HTTP spec: retrieval (GET), creation (POST), updating (PUT) and deletion (DELETE). If you’ve been working with RESTful resources for any length of time you will find that the code for each of these actions tends to look very similar largely due to the use of convention over configuration that Rails favours heavily.

Whilst looking at refactoring portions of our company intranet, it struck me that such duplication was rife and I set about eliminating it. Ever mindful that the best abstractions are extracted (just like Rails was), all of the ideas and code that follows have been extracted directly from our intranet application.

I’m not the only person who has recognised the duplication that tends to result from taking the RESTful approach and consequently some solutions for making development of RESTful applications exist already in the form of generators and scaffolding.

Existing solutions

The problem with generators is that they don’t actually solve the problem of duplication in the code – they simply make it easier to get up and running by generating boilerplate code for you to modify. But once the code is in place it is still something to be maintained.

The problem with scaffolding is the same problem that plagues the scaffolding that originally came with Rails – it provides a very generic abstraction with little in the way of flex points which means you usually end up overriding the scaffolded methods anyway. You can usually generate scaffolding directly into the source itself but this has all of the same problems as generators.

An alternative approach

My approach was to first attempt some small, fine-grained refactorings on my controllers such as Extract Method to make sure that the REST actions focussed on their core responsibilities and delegated to template methods for specific behaviour. A common example is the create action, which usually looks something like this:

def create
  @user = User.new(params[:user])
  if @user.save
    flash[:notice] = 'User created successfully'
    redirect_to user_url(@user)
  else
    flash[:error] = 'User creation failed'
    # some specific error handling
    render :action => 'new'
  end
rescue SomeException
  # exception handling here
end

After extracting functionality to template methods, I ended up with code like this:

def create
  user = User.new(params[:user])
  if user.save
    handle_successful_create_for user
  else
    handle_failed_create_for user
  end
rescue
  handle_exception_for_user
end

protected
  def handle_succesful_create_for user
    flash[:notice] = 'User creeated successfully'
    redirect_to user_url(user)
  end
    
  def handle_failed_create_for user
    @user = user
    flash[:error] = 'User creation failed'
    render :action => 'new'
  end

  def handle_exception_for user
    # exception handling here
  end

The same approach is taken for other methods and after making this refactoring I am now left with identical RESTful actions across my application. Some might feel that the next step was to extract a super-class but there was still some variation that hadn’t been eliminated – each controller worked with a different model. I was also somewhat uneasy about using inheritance to eliminate duplication – it is often a good idea to favour composition where possible1. However a solution that uses composition is awkward because the object model for Rails controllers is abstracted in the framework. Fortunately Ruby provides us with an alternative that allows us to avoid modifying the inheritance tree in the form of mixins. Using include and extend we are able to add functionality to classes and their instances. This is the approach I decided to take but that still left that pesky model variation to deal with.

Refactoring further: extending the DSL

Once again Ruby comes to the rescue with it’s excellent meta-programming functionality. We take advantage of that functionality all of the time in Rails when we use it’s macro-style class methods; filters and ActiveRecord associations and validations are great examples. Using meta-programming, it was relatively easy to come up with a small DSL for exposing resources with a controller. Here is the first part:

class UsersController < ApplicationController
  expose_resource :user
end

As it clearly states, this tells the UsersController that we want to expose our User model. We can use this value throughout whatever code we write to generate each action. The next thing to tackle was how to generate these actions at runtime. I studied the scaffolding code that comes with Rails but wasn’t really comfortable with treating code as a template and running it through an eval statement. I decided to take a more object-oriented approach and created a series of command objects to represent each action. This solution was easy to test and extend where necessary.

Finally, there needed to be some way of specifying what actions RESTful actions you want to expose – you might not want all seven. This lead to the second part of the DSL:

class UsersController < ApplicationController
  expose_resource :user, :except => [:update, :destroy]
end

Of course, you might only want a few of the actions:

class UsersController < ApplicationController
  expose_resource :user, :only => [:index, :show]
end

So where does that leave us? All of the core functionality is in place and all that the developer has to provide is an implementation of the various callback handlers. With some sensible default implementations to these handlers built-in, the developers life is made even easier.

One size does not fit all

It is worth noting that there isn’t a callback handler designed for every situation. Besides the sheer difficulty in guessing all of the flex-points that a developer might need, it would require a lot of bloated unnecessary code just to cater for edge cases. The above abstraction was never designed to cover all cases and I don’t believe any abstraction ever can. However it does make it possible to add functionality quickly at least 80% of the time and it handling the remaining 20% of cases is as simple as the developer providing their own hardcoded action.

All of the code discussed above is available as a Rails plugin that I’ve called restful_exposure. It can be checked out with Subversion at the following URL:

svn://lukeredpath.co.uk/opensource/plugins/restful_exposure/trunk

A README is bundled and all code is released under the MIT license.

Feedback

At present, most of the callback handlers are lacking implementation. This code is only a couple of days old and is not considered production-ready by a long shot. For starters, it is completely lacking any form of test coverage. I used our existing test coverage for our intranet to guide my way during refactoring but it is my plan to add a good suite of RSpec specifications. This isn’t even live on our intranet yet and currently lives on a branch of our intranet code.

In addition to the above functionality there are a few other features that came about as a direct result of extracting this from our intranet application. The first is the introduction of a parameterized index action. It is common to have some alternative collection actions as well as index – archives, search and recent are good examples. They both retrieve a collection of objects but the number of items retrieved, their order and how they are filtered varies. This variation is encapsulated by the index parameter which is passed into ActiveRecord::Base#find as its options hash. This lets you do things like this:

def recent
  index :limit => 5
end

Another thing that it was important to handle was nested resources, representing belongs_to/has_x relationships. One of the impacts this had on the code was in the creation of new objects – the new action had to ensure that the new object created (to be bound to the new form) was linked to its parent object. Getting the parameters for this is made easy by convention and URL parameters made available by nested resource routes so it wasn’t a problem to extract. This lead to the first option for expose_resource:

class FilesController < ApplicationController
  expose_resource :file, :nested_under => :folder
end

The second option came from the need to link new objects to their parent object when working with tree-like nesting of a single model using acts_as_tree. Support for this is built-in using the as_tree option:

class FolderController < ApplicationController
  expose_resource :folder, :as_tree => true
end

I’m well aware that the Rails community is an opionated one (naturally) and that this might not appeal to some people. Some people might perceive this as “too much magic”. Personally I’d disagree – I think this is no more magic here than has_many and acts_as_foo. It has been extracted from a real working application and I think that is important. I have a “3 strikes” rule when it comes to abstractions like this – if I’ve done the same thing three different times or on three different apps then its time to look for that abstraction and reduce the amount of code that needs maintaining. This “3 strikes”/abstract through extraction approach is exactly the same one that lead to my crypted_authentication plugin.

If you are working with RESTful resources and have found yourself typing the same thing over and over again, please do checkout the plugin and give it a try. I repeat, this is not production-ready but I’m really interested in people’s feedback on the approach and any suggestions. Do dig into the source to get an understanding of how I’ve approached the implementation. I’ve tried to avoid Ruby-fu “magic” wherever I can in favour of traditional object-oriented approaches.

Are there any areas such as the nesting/tree-like structures above that you find yourself doing often that would be a good fit for abstraction? What do you think of the API? Comments are open!

Update 05/02/2007: As per Steve’s suggestion in the comments below, I’ve modified the interface so that it uses just the single expose_resource call, with :only and :except options (:all by default) as per the Rails filters API. I’ve updated the code samples above to reflect this. expose_resource_actions has been removed.

1 It is a generally accepted object-oriented design rule – and one that I agree with and try to adhere to – that composition leads to less coupling and polution of the inheritance tree (which should really only really be used when objects really are of similar type). I also find it leads to more easily testable and elegant solutions.On Google.

Blog moved to Expressica.com — releasing the captcha plugin with multiple styles of clear images, with random string text

Posted over 7 years back at Ajax on Rails


Hi Everbody !!

I am moving this blog to Expressica

and i would like to inform all the readers to update their feeds and bookmarks to the new url http://expressica.com .

On my new blog i am going to release a captcha plugin which is really very simple to implement. This plugin provides the functionality to add captcha based authentication in your rails applications.

It mainly features…

  • Controller based captcha
  • Model based captcha
  • and the feature i like the most is multiple image styles

You can simply pass the name of the image style from the view and captcha will throw the random strings as the selected style of image. The images are clear enough to read by human and blurred and manipulated enough to protect from bots.
Example of the images …

  • simply_red
  • simply_green
  • simply_blue
  • embosed_silver
  • distorted_black
  • all_black
  • charcoal_grey
  • almost_invisible

Comments/Queries are welcome on this idea.

I will release this plugin very soon on Expressica.com

ANSI Strings: your fun-loving, colourful pal (quick-fix colour library)

Posted over 7 years back at Wood for the Trees

You can make your command line interface look a little better than just a bungle of white on black (or however you or your users set your terminal). In my on-going development of a few little open source projects, all of them with CLIs, I abstracted this cute addition to the Ruby snippets junkyard and decided to air it.

With it, you can wrap any string with ANSI codes like this:

  "I am going to be bold and cyan!".bold.cyan
  "I am going to be underlined. YAY!".underline
  "Oh, for the love of God... please STOP BLINKING!".blink

Make your command line interface glisten with choice and sparing use of ANSI codes not just with the above methods dynamically added to the String class, but also by using with_ansi(*ansi_aliases). It’s really very simple. Also, all application of ANSI is dependent on $ANSI being true, which, by default, is false (as you can at the bottom of this article, in the first line of code). Lastly, ANSI Strings checks the current platform and won’t be applied to strings on a win32 platform—I have no way of testing whether win32 can in certain instances show colour, so I just disable it.

You can download ANSI Strings from my googlecode repository like so:

 svn co http://mabs29.googlecode.com/svn/trunk/other/ansi_strings

Or you can just look at it here, since it is so simple and small:

$ANSI ||= true

class String

  ANSI_CODES = {
    :normal         => [0, "m"],
    :bold           => [1, "m"],
    :underline      => [4, "m"],
    :blink          => [5, "m"],
    :reverse_video  => [7, "m"],
    :invisible      => [8, "m"],

    :black          => [30, "m"],
    :red            => [31, "m"],
    :green          => [32, "m"],
    :yellow         => [33, "m"],
    :blue           => [34, "m"],
    :magenta        => [35, "m"],
    :cyan           => [36, "m"],
    :white          => [37, "m"],

    :black_bg       => [40, "m"],
    :red_bg         => [41, "m"],
    :green_bg       => [42, "m"],
    :yellow_bg      => [43, "m"],
    :blue_bg        => [44, "m"],
    :magenta_bg     => [45, "m"],
    :cyan_bg        => [46, "m"],
    :white_bg       => [47, "m"]
  }

  # Create shortcuts to wrap any string with ansi codes
  ANSI_CODES.keys.each { |meth| define_method(meth) { with_ansi(meth) } }

  # Wrap a string with an arbitrary ansi code and the ansi normal code
  def with_ansi(*codes)
    use_ansi? ? "#{sym_to_ansi(*codes)}#{self}#{sym_to_ansi(:normal)}" : self
  end

  private
  def sym_to_ansi(*symbols)
    symbols.inject("") do |string, symbol|
      string << "\033[%s%s" % ANSI_CODES[symbol] if ANSI_CODES[symbol]; string
    end
  end

  # determine whether we have ansi support or ANSI enabled
  def use_ansi?
    $ANSI && RUBY_PLATFORM !~ /win32/i
  end

end

ANSI Strings: your fun-loving, colourful pal (quick-fix colour library)

Posted over 7 years back at Wood for the Trees

You can make your command line interface look a little better than just a bungle of white on black (or however you or your users set your terminal). In my on-going development of a few little open source projects, all of them with CLIs, I abstracted this cute addition to the Ruby snippets junkyard and decided to air it.

With it, you can wrap any string with ANSI codes like this:

  "I am going to be bold and cyan!".bold.cyan
  "I am going to be underlined. YAY!".underline
  "Oh, for the love of God... please STOP BLINKING!".blink

Make your command line interface glisten with choice and sparing use of ANSI codes not just with the above methods dynamically added to the String class, but also by using with_ansi(*ansi_aliases). It’s really very simple. Also, all application of ANSI is dependent on $ANSI being true, which, by default, is false (as you can at the bottom of this article, in the first line of code). Lastly, ANSI Strings checks the current platform and won’t be applied to strings on a win32 platform—I have no way of testing whether win32 can in certain instances show colour, so I just disable it.

You can download ANSI Strings from my googlecode repository like so:

 svn co http://mabs29.googlecode.com/svn/trunk/other/ansi_strings

Or you can just look at it here, since it is so simple and small:

$ANSI ||= true

class String

  ANSI_CODES = {
    :normal         => [0, "m"],
    :bold           => [1, "m"],
    :underline      => [4, "m"],
    :blink          => [5, "m"],
    :reverse_video  => [7, "m"],
    :invisible      => [8, "m"],

    :black          => [30, "m"],
    :red            => [31, "m"],
    :green          => [32, "m"],
    :yellow         => [33, "m"],
    :blue           => [34, "m"],
    :magenta        => [35, "m"],
    :cyan           => [36, "m"],
    :white          => [37, "m"],

    :black_bg       => [40, "m"],
    :red_bg         => [41, "m"],
    :green_bg       => [42, "m"],
    :yellow_bg      => [43, "m"],
    :blue_bg        => [44, "m"],
    :magenta_bg     => [45, "m"],
    :cyan_bg        => [46, "m"],
    :white_bg       => [47, "m"]
  }

  # Create shortcuts to wrap any string with ansi codes
  ANSI_CODES.keys.each { |meth| define_method(meth) { with_ansi(meth) } }

  # Wrap a string with an arbitrary ansi code and the ansi normal code
  def with_ansi(*codes)
    use_ansi? ? "#{sym_to_ansi(*codes)}#{self}#{sym_to_ansi(:normal)}" : self
  end

  private
  def sym_to_ansi(*symbols)
    symbols.inject("") do |string, symbol|
      string << "\033[%s%s" % ANSI_CODES[symbol] if ANSI_CODES[symbol]; string
    end
  end

  # determine whether we have ansi support or ANSI enabled
  def use_ansi?
    $ANSI && RUBY_PLATFORM !~ /win32/i
  end

end

Blog Package Ponderings

Posted over 7 years back at zerosum dirt(nap) - Home

Drupal has served me pretty well for a number of projects in the past. But as we shift our development focus towards Ruby-based projects, it seems like an ideal time to consider migrating my own blogging platform to something Rails-driven. Nothing against Drupal itself of course. Hell, for a PHP project it’s pretty slick.

But it still just leaves me feeling like I’m flirting with an old (and somewhat unattractive) ex-girlfriend. It’s not you, it’s me.

The obvious candidates seem to be Typo and Mephisto. Another option would be to, of course, roll my own. But does the world really need another half-baked blogging engine? Probably not. If anyone has other recommendations let me know. Looks like I’m leaning towards Mephisto at this point.

Hobo 0.4.3

Posted over 7 years back at The Hobo Blog

May we present, for your pleasure, Hobo version 0.4.3

* hobo-0.4.3.gem

* Change Log

Let’s see… what to tell you about the new stuff? There’s a nice little DSL for integration tests. Most of the goodness is already there with Rails (See Jamis Buck’s blog post). I’ve just added a few convenient methods for testing basic stuff like creating and viewing objects. Here’s a snippet from a test of the POD demo:

def test_user_creating
  fred = fred_session
  new_ad = fred.creates_and_visits(Advert, 
                                 :title => "my car",
                                 :body => "is a nice car",
                                 :category => cars)
  fred.sees new_ad.title
  fred.sees new_ad.body

  fred.cant_create(User, :username => "Jim")
  fred.cant_create(Category,
                   :name => "small furry creatures")
end

Neat eh?

Enjoy.

Hobo 0.4.3

Posted over 7 years back at The Hobo Blog

May we present, for your pleasure, Hobo version 0.4.3

* hobo-0.4.3.gem

* Change Log

Let’s see… what to tell you about the new stuff? There’s a nice little DSL for integration tests. Most of the goodness is already there with Rails (See Jamis Buck’s blog post). I’ve just added a few convenient methods for testing basic stuff like creating and viewing objects. Here’s a snippet from a test of the POD demo:

def test_user_creating
  fred = fred_session
  new_ad = fred.creates_and_visits(Advert, 
                                 :title => "my car",
                                 :body => "is a nice car",
                                 :category => cars)
  fred.sees new_ad.title
  fred.sees new_ad.body

  fred.cant_create(User, :username => "Jim")
  fred.cant_create(Category,
                   :name => "small furry creatures")
end

Neat eh?

Enjoy.

Shysters

Posted over 7 years back at Ryan Tomayko's Writings

Tim Bray’s take on the Microsoft/Wikipedia mess is enlightening but this bit at the end blew my mind:

Netscape hired me to represent their interests, and when I announced this, controversy ensued. Which is a nice way of saying that Microsoft went berserk; tried unsuccessfully to get me fired as co-editor, and then launched a vicious, deeply personal extended attack in which they tried to destroy my career and took lethal action against a small struggling company because my wife worked there. It was a sideshow of a sideshow of the great campaign to bury Netscape and I’m sure the executives have forgotten; but I haven’t.

Wow.

Where I come from we have a word for this kind of stuff: shystie. It’s not a label applied carelessly and once applied it’s almost impossible to shake because it means you cannot be trusted.

You don’t associate with shysters. You don’t try to help or understand them. You stay away.

Shystiness is a terminal disease.

I think this gets to the root of my issue with the recent round of smart and reputable people going to Microsoft. Ozzie, Hugunin, Udell: all insanely smart and respectable individuals. I want to like that company again, I really do, but they’re shystie. It’s a deal breaker.

EDIT: I felt bad after posting this. I'm not sure why because I feel pretty strongly about the sentiment. At any rate, this comment from Mike Champion, one of the folks at MS I have a large amount of respect for, balances out my cynicism a bit:

Finally, on “Which is a nice way of saying that Microsoft went berserk”: To be frank, I watched that episode 10 years ago with horror, and had my own issues with some Microsoft people and the rather arrogant corporate culture back in the ‘90s too. But things change … I guess the perpetrators are now retired and living off their stock options proceeds. Life is unfair, but it goes on, the lawyers move in, and I'm quite sure that that kind of thing wouldn’t happen today. Give MS credit for one thing: they don’t hire dummies (well, maybe I'm an exception) and smart people learn from their mistakes.

Clearly, the shystiness at MS is not a trait shared by everyone. The good guys need to find a way to get out in front of the shysters in a big way.

Bha. I'm breaking my own rules now.

What is Hobo?

Posted over 7 years back at The Hobo Blog

There’s a fair few reactions to Hobo out there on the big wide Internets by now, and it’s interesting to see people’s interpretations. I suppose it’s pretty obvious that people are going to jump to conclusions when I’ve only given a brief glimpse of what Hobo is about. I just wanted to take a quick moment to clear a few things up. Update: this turned from a “quick moment” into a fairly comprehensive overview of what Hobo can do :-)

The main point here is this - Hobo is nothing but extensions to Rails! There’s nothing that Rails can do that Hobo can’t. I’m not saying that Hobo will be to everyone’s taste - of course you may prefer Rails as it is. I’m just making the point that Hobo only adds to Rails, it doesn’t take anything away. Perhaps it’s the slightly “magic” feel to the POD screencast – I can see that the screencast might leave some people thinking they’d rather build the app themselves and have control over everything. So I guess I’m really just making the point that you do have control over everything, in just as direct a manner as you do in Rails without Hobo.

Hobo does do more than your average plugin though – it’s kind of like several plugins rolled into one. Inevitably people are going to be interested in having those features as separate plugins – a few people have asked for DRYML by itself already. But there are a bunch of dependencies between the different features, and to be honest I won’t know exactly where things can be separated until Hobo matures a bit.

So, for now at least, I’ve taken a different approach - you install all these features at once by installing Hobo, but you use only those features you want to. If you want the whole “web app builder” thing, then you’ll end up using most or all of them, but if you just want DRYML? Not a problem, the rest of Hobo won’t get in your way. If you later see that you could also benefit from, say, the ajax-mechanism, fine – just start using it.

So perhaps a quick tour of what these features are would be in order :-)

DRYML

This is really the heart of Hobo – it all started with DRYML. There’s a few posts on this already of course - have a look in the documentation category. DRYML consists of the templating mechanism itself, as well as a “core” tag library, with the basic things like loops and conditionals.

Ajax Rendering

Building on DRYML, this is the ability to mark a section of your page as a “part”. Having done this, Hobo will track the object that was in context when the part was rendered, and can re-render the part using the new state of that object when requested. This mechanism can be used by itself, but works best in combination with the Hobo Rapid tag library, which lets you write very simple stuff like

<delete_button update="number_of_users"/>

and the number of users will automatically change to reflect the deletion.

Right now using the Ajax mechanism without also buying into Hobo Rapid is kind of a pain. Some extra work to smooth that out is in order. Perhaps some regular Rails helpers.

Hobo Rapid Tag Library

This is where things get groovy. A tag library is basically just like a load of Rails helpers, but as DRYML tags instead of methods. Hobo Rapid contains the Hobo equivalent of link helpers, form helpers, ajax helpers, and pagination helpers. There’s also some “scaffold-like” tags for default pages, and support for navigation bars.

This library is expected to grow!

ActiveRecord Permission System

This appears prominently in the POD screencast. At it’s heart it’s just a simple convention for declaring who’s allowed to do what to your models (create, update, delete and view). The permissions come into effect in two places: in customising the views, and in validating http requests.

View customisation is provided in the tag library. The output of various tags is dependent on permissions. For example the <edit> tag will automatically become a read-only view if the current user does not have edit permission.

Validation of web requests is done in Hobo’s generic model controller (see below). If the request, be it a view, a create, an update or a delete (http get/post/put/delete) is not permitted for the current user, it will be rejected.

Fairly simple but useful. Models can declare which columns are searchable (there are sensible defaults of course!) and Hobo provides both server and client-side support for a nice ajaxified search that finds many types of model from a single search page.

Switchable Themes

A Hobo theme consists of public assets such as a stylesheet and images, and some tag definitions. The tags define the basic HTML structure of the various theme elements - the overall page, header and footer, navigation bar, sidebars, panels (boxed sections within the page) etc. Themes are switchable by changing a configuration variable. All the variable does is determine the paths used to find the tag definitions (app/views/hobolib/themes/theme-name) and the public assets (public/hobothemes/theme-name).

User Management (Acts As Authenticated)

In order for the permission system to work, a user model must be present. For that reason we decided to go ahead and include AAA in Hobo. It’s been tweaked a bit – the controller has been merged with Hobo’s “front” controller (so called because it gives you your front page and related pages like search, login and signup). The user model methods that are not commonly changed have been moved out into a module to keep your user model clean.

Hobo also adds the concept of a guest user, this is a pseudo model that is not stored in the database. It’s just a place to define the permissions for someone who has not logged in. One implication of this change this is that instead of testing if current_user is nil, you test for current_user.guest?.

ActiveRecord Composable Query Mechanism

It’s common practice with ActiveRecord to write query methods to capture standard queries your application needs beyond the magic find_by_thingumybob methods. A problem I ran into was that I wanted to be able to compose queries: find everything that matches this query or that one; find the first record that matches some query and some other one.

I found I needed such a feature in Hobo so I implemented the following:

Post.find(:all) { (title_contains("Hobo") | content_contains("Hobo")) &
                   is_in(news_category.posts) }
User.find(:first) { name_is("Tom") | email_is("foo@bar.com") }

Note that in the first example, the collection my_category.posts doesn’t need to be loaded - the query generates SQL and runs entirely on the database.

The query operations in those examples – *_contains, *_is and in_collection – are all built in. If you write class methods on your model that return SQL expressions you can use those in the query too.

Generic Model Controller (CRUD Support)

Hmmm - this does a fair few things. Maybe I need another cup of tea… Slurp, ahhh. Sorry where was I? Oh yeah - the model controller. To get this functionality, add this to your controller

hobo_model_controller

It’s just a short-hand for including Hobo::ModelController. You can also generate a controller which already contains this declaration (hey - every little helps!) with:

$ ./script/generate hobo_model_controller <model-name>

CRUD support

Hobo derives the model class from the controller class name, so you should follow the Rails convention of PostsController for model Post (the generator will do this for you of course). You then get the basic CRUD methods familiar from scaffolding: index, show, new, create, edit and update.

The controller also has support for your has_many and belongs_to associations. Firstly, your has_many associations get published automatically, so for example the URL

/posts/12/comments

Would map to the action show_comments, which is implemented for you. Also

/posts/12/comments/new

Will invoke the new_comment action - again it’s implemented for you. Note that the form on that page doesn’t post to /posts/12/comments but to /comments as usual. I decided it was best to have a single URL for creating a given model.

There’s also support for your associations when creating / updating models. Without going into too much detail in this overview, when you post (create) or put (update), you can set both has_many associations and belongs_to associations. You can either pass the id of an existing record, or pass entirely new records in nested parameter hashes. There’s support for all this in DRYML and Hobo Rapid, so for example if a person has an address as a separate, associated model, you can easily build a single form with fields for both the person and the associated address.

Data filters

The composable query mechanism for ActiveRecord has been described above. Data filters allow you to expose these queries to the web. This is easiest to explain with an example. Say we have people that are members of groups, and we want a page with all the people not in a particular group. Inside the people controller we define a data filter:

def_data_filter :not_in do |collection|
  not_in(collection)
end

A page with all the people not in the group with id 7 would then be available at

/people?where_not_in=group_17

Enhanced autocomplete

Rails already has support for working with the Scriptaculous auto-completer through the helper auto_complete_for (although that’s on its way out in 2.0). Hobo’s version is enhanced to work with the data filter mechanism. Say for example you wanted an auto-completer to allow you to add people to a list - you don’t want the people already in the list to be included in the completions. You would add the following to your controller:

def_data_filter :not_in do |collection|
  not_in(collection)
end

autocomplete_for :name

You would then point your auto-completer at (e.g.) /people/completions?for=name&where_not_in=list_12

Hobo Rapid has an auto-completer tag so the client side is nice and easy too.

Remote procedure calls

When DHH introduced the Simply Restful stuff, he described CRUD as an aspiration rather than a hard rule (IIRC). In other words, you shouldn’t go crazy trying to model absolutely everything as resources – there will still be “remote procedure calls” (RPC) that we post to. I hit this recently with a need for a “reset password” service on an app I’m building. (BTW - this is basically how Hobo moves forward - if I hit a need for a feature that I feel will crop up again and again, I build it into Hobo, not the app. In this case I didn’t want to build password reset into Hobo, but I did build the RPC mechanism).

The basic procedure is: write an action in your controller as normal. Add web_method <method-name>. Hobo will add a route for your method, and apply a before filter so the object in question is already available in @this. Hobo’s ajax mechanism supports updating the page with results from your method, and there’s integration into the permission system too.

Let’s see an example - the reset password method. In the controller we add:

web_method :reset_password
def reset_password
  new_password = @this.reset_password
  hobo_ajax_response(@this, :password => new_password)
end

On the model we can add a method can_call_reset_password?(user). In my case I only wanted the super-user to have access to this method so I didn’t need can_call_reset_password?.

The method will be available to HTTP posts at, e.g.

/users/21/reset_password

For the client side there’s a <remote_method_button> tag (note to self: should be called <web_method_button>?)

Alternative show methods

Simply Restful introduced the semicolon in the URL to access alternate views of the same object. So

/posts/12

Would be a ‘normal’ view of the post, while

/post/12;edit

Would give you a form to edit the post – still a view of the post, just a different one. You’ll probably find the need for additional “alternative views”, e.g. you might have a main view of a user, plus a separate “My Profile” page where users can edit details that don’t change so often, like their email address. Hobo allows you to simply say

show_method :profile

In your controller. You then create app/views/users/profile.dryml. You also get a named route person_profile so you can call person_profile_url(fred) and get the URL back.

Migration Enhancements

This is a little one, but very useful. In create_table calls, you can add columns like this

t.string :name, :subject, :limit => 50

instead of

t.column :name, :string, :limit => 50
t.column :subject, :string, :limit => 50

There’s also t.auto_dates that gives you updated_at and created_at, and

t.fkey :zip, :zap

That will give you integer columns zip_id and zap_id.

ID Names

In ActiveRecord everything has a numeric ID. It’s common however, that models also have an identifying name (e.g. a name column where every row is unique). If a model has an ID name like this, it’s nice to be able to sometimes use it instead of the numeric ID, for example in readable URLs. If your model declares hobo_model, you can also declare

id_name <column-name>

If you don’t specify a column it defaults to name. This gives you a read/write attribute id_name which is just an alias for the column in question. You also get find_by_id_name on the class.

If you are using Hobo’s model_controller you can then use names instead of IDs in your URLs, e.g. (using ID names in combination with the associations support):

/categories/News/posts

The helper object_url will generate this kind of URL too - if the object you pass supports ID names.

That’s All Folks!

That’s pretty much everything, although of course lots of detail is lacking. Oh and there’s a ton of great new stuff just around the corner of course!

What is Hobo?

Posted over 7 years back at The Hobo Blog

There’s a fair few reactions to Hobo out there on the big wide Internets by now, and it’s interesting to see people’s interpretations. I suppose it’s pretty obvious that people are going to jump to conclusions when I’ve only given a brief glimpse of what Hobo is about. I just wanted to take a quick moment to clear a few things up. Update: this turned from a “quick moment” into a fairly comprehensive overview of what Hobo can do :-)

The main point here is this - Hobo is nothing but extensions to Rails! There’s nothing that Rails can do that Hobo can’t. I’m not saying that Hobo will be to everyone’s taste - of course you may prefer Rails as it is. I’m just making the point that Hobo only adds to Rails, it doesn’t take anything away. Perhaps it’s the slightly “magic” feel to the POD screencast – I can see that the screencast might leave some people thinking they’d rather build the app themselves and have control over everything. So I guess I’m really just making the point that you do have control over everything, in just as direct a manner as you do in Rails without Hobo.

Hobo does do more than your average plugin though – it’s kind of like several plugins rolled into one. Inevitably people are going to be interested in having those features as separate plugins – a few people have asked for DRYML by itself already. But there are a bunch of dependencies between the different features, and to be honest I won’t know exactly where things can be separated until Hobo matures a bit.

So, for now at least, I’ve taken a different approach - you install all these features at once by installing Hobo, but you use only those features you want to. If you want the whole “web app builder” thing, then you’ll end up using most or all of them, but if you just want DRYML? Not a problem, the rest of Hobo won’t get in your way. If you later see that you could also benefit from, say, the ajax-mechanism, fine – just start using it.

So perhaps a quick tour of what these features are would be in order :-)

DRYML

This is really the heart of Hobo – it all started with DRYML. There’s a few posts on this already of course - have a look in the documentation category. DRYML consists of the templating mechanism itself, as well as a “core” tag library, with the basic things like loops and conditionals.

Ajax Rendering

Building on DRYML, this is the ability to mark a section of your page as a “part”. Having done this, Hobo will track the object that was in context when the part was rendered, and can re-render the part using the new state of that object when requested. This mechanism can be used by itself, but works best in combination with the Hobo Rapid tag library, which lets you write very simple stuff like

<delete_button update="number_of_users"/>

and the number of users will automatically change to reflect the deletion.

Right now using the Ajax mechanism without also buying into Hobo Rapid is kind of a pain. Some extra work to smooth that out is in order. Perhaps some regular Rails helpers.

Hobo Rapid Tag Library

This is where things get groovy. A tag library is basically just like a load of Rails helpers, but as DRYML tags instead of methods. Hobo Rapid contains the Hobo equivalent of link helpers, form helpers, ajax helpers, and pagination helpers. There’s also some “scaffold-like” tags for default pages, and support for navigation bars.

This library is expected to grow!

ActiveRecord Permission System

This appears prominently in the POD screencast. At it’s heart it’s just a simple convention for declaring who’s allowed to do what to your models (create, update, delete and view). The permissions come into effect in two places: in customising the views, and in validating http requests.

View customisation is provided in the tag library. The output of various tags is dependent on permissions. For example the <edit> tag will automatically become a read-only view if the current user does not have edit permission.

Validation of web requests is done in Hobo’s generic model controller (see below). If the request, be it a view, a create, an update or a delete (http get/post/put/delete) is not permitted for the current user, it will be rejected.

Fairly simple but useful. Models can declare which columns are searchable (there are sensible defaults of course!) and Hobo provides both server and client-side support for a nice ajaxified search that finds many types of model from a single search page.

Switchable Themes

A Hobo theme consists of public assets such as a stylesheet and images, and some tag definitions. The tags define the basic HTML structure of the various theme elements - the overall page, header and footer, navigation bar, sidebars, panels (boxed sections within the page) etc. Themes are switchable by changing a configuration variable. All the variable does is determine the paths used to find the tag definitions (app/views/hobolib/themes/theme-name) and the public assets (public/hobothemes/theme-name).

User Management (Acts As Authenticated)

In order for the permission system to work, a user model must be present. For that reason we decided to go ahead and include AAA in Hobo. It’s been tweaked a bit – the controller has been merged with Hobo’s “front” controller (so called because it gives you your front page and related pages like search, login and signup). The user model methods that are not commonly changed have been moved out into a module to keep your user model clean.

Hobo also adds the concept of a guest user, this is a pseudo model that is not stored in the database. It’s just a place to define the permissions for someone who has not logged in. One implication of this change this is that instead of testing if current_user is nil, you test for current_user.guest?.

ActiveRecord Composable Query Mechanism

It’s common practice with ActiveRecord to write query methods to capture standard queries your application needs beyond the magic find_by_thingumybob methods. A problem I ran into was that I wanted to be able to compose queries: find everything that matches this query or that one; find the first record that matches some query and some other one.

I found I needed such a feature in Hobo so I implemented the following:

Post.find(:all) { (title_contains("Hobo") | content_contains("Hobo")) &
                   is_in(news_category.posts) }
User.find(:first) { name_is("Tom") | email_is("foo@bar.com") }

Note that in the first example, the collection my_category.posts doesn’t need to be loaded - the query generates SQL and runs entirely on the database.

The query operations in those examples – *_contains, *_is and in_collection – are all built in. If you write class methods on your model that return SQL expressions you can use those in the query too.

Generic Model Controller (CRUD Support)

Hmmm - this does a fair few things. Maybe I need another cup of tea… Slurp, ahhh. Sorry where was I? Oh yeah - the model controller. To get this functionality, add this to your controller

hobo_model_controller

It’s just a short-hand for including Hobo::ModelController. You can also generate a controller which already contains this declaration (hey - every little helps!) with:

$ ./script/generate hobo_model_controller <model-name>

CRUD support

Hobo derives the model class from the controller class name, so you should follow the Rails convention of PostsController for model Post (the generator will do this for you of course). You then get the basic CRUD methods familiar from scaffolding: index, show, new, create, edit and update.

The controller also has support for your has_many and belongs_to associations. Firstly, your has_many associations get published automatically, so for example the URL

/posts/12/comments

Would map to the action show_comments, which is implemented for you. Also

/posts/12/comments/new

Will invoke the new_comment action - again it’s implemented for you. Note that the form on that page doesn’t post to /posts/12/comments but to /comments as usual. I decided it was best to have a single URL for creating a given model.

There’s also support for your associations when creating / updating models. Without going into too much detail in this overview, when you post (create) or put (update), you can set both has_many associations and belongs_to associations. You can either pass the id of an existing record, or pass entirely new records in nested parameter hashes. There’s support for all this in DRYML and Hobo Rapid, so for example if a person has an address as a separate, associated model, you can easily build a single form with fields for both the person and the associated address.

Data filters

The composable query mechanism for ActiveRecord has been described above. Data filters allow you to expose these queries to the web. This is easiest to explain with an example. Say we have people that are members of groups, and we want a page with all the people not in a particular group. Inside the people controller we define a data filter:

def_data_filter :not_in do |collection|
  not_in(collection)
end

A page with all the people not in the group with id 7 would then be available at

/people?where_not_in=group_17

Enhanced autocomplete

Rails already has support for working with the Scriptaculous auto-completer through the helper auto_complete_for (although that’s on its way out in 2.0). Hobo’s version is enhanced to work with the data filter mechanism. Say for example you wanted an auto-completer to allow you to add people to a list - you don’t want the people already in the list to be included in the completions. You would add the following to your controller:

def_data_filter :not_in do |collection|
  not_in(collection)
end

autocomplete_for :name

You would then point your auto-completer at (e.g.) /people/completions?for=name&where_not_in=list_12

Hobo Rapid has an auto-completer tag so the client side is nice and easy too.

Remote procedure calls

When DHH introduced the Simply Restful stuff, he described CRUD as an aspiration rather than a hard rule (IIRC). In other words, you shouldn’t go crazy trying to model absolutely everything as resources – there will still be “remote procedure calls” (RPC) that we post to. I hit this recently with a need for a “reset password” service on an app I’m building. (BTW - this is basically how Hobo moves forward - if I hit a need for a feature that I feel will crop up again and again, I build it into Hobo, not the app. In this case I didn’t want to build password reset into Hobo, but I did build the RPC mechanism).

The basic procedure is: write an action in your controller as normal. Add web_method <method-name>. Hobo will add a route for your method, and apply a before filter so the object in question is already available in @this. Hobo’s ajax mechanism supports updating the page with results from your method, and there’s integration into the permission system too.

Let’s see an example - the reset password method. In the controller we add:

web_method :reset_password
def reset_password
  new_password = @this.reset_password
  hobo_ajax_response(@this, :password => new_password)
end

On the model we can add a method can_call_reset_password?(user). In my case I only wanted the super-user to have access to this method so I didn’t need can_call_reset_password?.

The method will be available to HTTP posts at, e.g.

/users/21/reset_password

For the client side there’s a <remote_method_button> tag (note to self: should be called <web_method_button>?)

Alternative show methods

Simply Restful introduced the semicolon in the URL to access alternate views of the same object. So

/posts/12

Would be a ‘normal’ view of the post, while

/post/12;edit

Would give you a form to edit the post – still a view of the post, just a different one. You’ll probably find the need for additional “alternative views”, e.g. you might have a main view of a user, plus a separate “My Profile” page where users can edit details that don’t change so often, like their email address. Hobo allows you to simply say

show_method :profile

In your controller. You then create app/views/users/profile.dryml. You also get a named route person_profile so you can call person_profile_url(fred) and get the URL back.

Migration Enhancements

This is a little one, but very useful. In create_table calls, you can add columns like this

t.string :name, :subject, :limit => 50

instead of

t.column :name, :string, :limit => 50
t.column :subject, :string, :limit => 50

There’s also t.auto_dates that gives you updated_at and created_at, and

t.fkey :zip, :zap

That will give you integer columns zip_id and zap_id.

ID Names

In ActiveRecord everything has a numeric ID. It’s common however, that models also have an identifying name (e.g. a name column where every row is unique). If a model has an ID name like this, it’s nice to be able to sometimes use it instead of the numeric ID, for example in readable URLs. If your model declares hobo_model, you can also declare

id_name <column-name>

If you don’t specify a column it defaults to name. This gives you a read/write attribute id_name which is just an alias for the column in question. You also get find_by_id_name on the class.

If you are using Hobo’s model_controller you can then use names instead of IDs in your URLs, e.g. (using ID names in combination with the associations support):

/categories/News/posts

The helper object_url will generate this kind of URL too - if the object you pass supports ID names.

That’s All Folks!

That’s pretty much everything, although of course lots of detail is lacking. Oh and there’s a ton of great new stuff just around the corner of course!

Markaby vs Haml vs ERB for Page Templates

Posted over 7 years back at zerosum dirt(nap) - Home

I’ve been spending some time lately looking at different templating packages for Rails, in hopes of finding something cleaner and sexier than the standard ERB (rhtml) recipe, that also helps avoid common HTML pitfalls that cause pages not to validate.

My search has pretty much boiled down to two candidates at this point. The first is Markaby, which has been around for a while now and lets us represent our XHTML in Ruby code. The other candidate is the new kid on the block, Haml, which just reached a 1.0 last week and has it’s own proprietary CSS-ish syntax. Let’s take a look at brief look at both of them…

Here’s some ERB:

<div class="column" id="content">
  <h2 class="entry_title"><%= h @thing.name %></h2>
  <div class="entry_link"><%= link_to('link', @thing.link) %></div>
</div>

This is probably what we’re all used to and there’s no arguing that it works well enough, but… Well, it’s kind of ugly, isn’t it? To represent this same thing in Markaby, we install the plugin and create a template with a .mab extension and stick this in it:

div.column.content! {
  h2.entry_title @thing.name
  div.entry_link link_to 'link', @thing.link
}

That sure looks better to me. Nice and compact, clean. The best part is that Markaby is actually valid Ruby syntax. This buys us a couple things: first of all, it means that our view won’t run at all if we end up with a syntax error in it, which in turn means that it’s valid XHTML. Slick.

The downside is, of course, performance. It requires rendering for every single tag and property, which makes it slow in comparison to ERB, since just the inline Ruby snippets in the rhtml file have to be processed and inserted into a mostly pre-rendered HTML template. I also have some minor gripes about the use of bang instead of pound for representing element IDs, and the fact that it blows up when I put a yield in my Markaby layout code (I have to use @content_for_layout, which is deprecated now).

Anyway, enough about that. Let’s talk about Haml for a second. Install the plugin, and create a view with a .haml extension. Here’s the same chunk of code we saw before written in Haml:

.column#content
  %h2.entry_title= @thing.name
  .entry_link= link_to('link', @thing.link)

Haml defines it’s own syntax, which borrows from familiar CSS markup, and takes advantage of whitespace sensitivity for nesting. This latter bit is great news if you’re one of those undercover Python people hiding amongst us (I’m not one of you, now go away). It generates really nice clean appropriately nested HTML for output too.

Although it’s fairly easy to read and satisfies our cleanliness criteria, there are some immediate downsides to the fact that the markup is proprietary. Firstly, it means the files still have to be parsed and re-rendered by Rails, for a performance hit — same as we’d get with Markaby or any other higher-level template language for that matter. It also means that your editor isn’t going to be able to help you with syntax highlighting unless it has explicit support through a plugin.

I can see why people like Haml, it’s compact and kind of fun (see the tutorial for more). But all things considered, I really can’t see any reason I’d use it instead of Markaby, which feels much more natural to me and has the added benefit of Ruby syntax validation. Perhaps if it were to represent a significant performance increase — this seems doubtful — but I haven’t seen any real benchmarks. In any case, I don’t think I’ll be using it any time soon.

If I were to choose one of these two, I’d have to go with Markaby. I’m quite smitten by the idea of writing template code in pure Ruby, and the syntax validation enforcement is extremely desirable. As bizarre as it may seem, I love the idea of a page failing to run because of a syntax error in my “HTML” markup. Still, the performance issues give me pause. An even bigger issue is that of fragment caching, which sadly seems to be currently busted in Markaby. So, all things considered, I guess I’m sticking with ERB in my view templates, coupled with assert_valid_markup for my validation testing needs. At least for now. Even thought it makes me cringe a bit.

If I’ve missed anything worth considering about either of these templates, or if there are other options, please drop me a line. I’d love to hear what the rest of the community is using for their high-volume web apps…