Yehuda Katz is a member of the Ember.js, Ruby on Rails and jQuery Core Teams; he spends his daytime hours at the startup he founded, Tilde Inc.. Yehuda is co-author of best-selling jQuery in Action and Rails 3 in Action. He spends most of his time hacking on open source—his main projects, like Thor, Handlebars and Janus—or traveling the world doing evangelism work. He can be found on Twitter as @wycats and on Github.
Merb 0.4 — The One That Rocks!
November 6th, 2007
So I’ve been talking quite a bit about Merb on my blog, and for those of you who could care less, I apologize. The Merb 0.4 pre-release will be coming out tomorrow, and I wanted to preview some of the really need features that have been added since 0.3.7.
- Generators: Thanks to DrNic’s rubigen, we have full-fledged generators now. But it gets better. Our generators use the ORM and Testing framework you’re using to generate specific files that are appropriate. So if you do
script/generate model Fooand are running DataMapper with RSpec, you’ll get new model files for DataMapper, and new spec files for RSpec (same with ActiveRecord, and Test::Unit, of course).
- Parameterized Actions: If you specify parameters in your action methods, incoming query parameters will automatically get assigned as appropriate. Some examples:
class Foos < Merb::Controller def index(id, search_string = "%") @foo = Foo.find_with_search(id, search_string) end end
/foos/index/12will call the index method with the parameters "12" and "%" (the default provided). Going to
/foos/indexwill throw a
BadBehaviorerror (status code 400) because id is a required parameter, but it was not passed in. Going to
/foos/index/5?search_string=hellowill call the index method with parameters "5" and "hello". The bottom line is that you get to use your actions like real methods. Of course, the params hash is still available and is provided untouched.
- Great Exception Handling: When an exception is raised inside a Merb::Controller, it is automatically delegated to the Exception Controller, where you can easily specify special behavior or custom templates. Since Exceptions are now just actions inside a controller (a NotFound error renders Exception#not_found), you can take advantage of layouts, helpers, filters, and assigned variables in your error screens.
- Awesome Developer Mode stack traces: The developer mode exceptions all render a stack trace, in which each line is both clickable (and will pull up the affected file in Textmate) and expandable (you can get a quick overview of the surrounding lines of code without having to open up your editor)
- Great content-type negotiation: Instead of laboriously doing a respond_to for every action, for each content-type, you can use strong declarative syntax and sensible defaults to slim down your controllers:
class Users < Merb::Controller provides :xml, :json def index @users = User.all render @users end def show(id) @user = User[id] render @user end end
The example shown above uses DataMapper, but the idea is simple. You declare, in your controller, which content-types will be supported. Then the browser sends the requested content-type (either via the content-type header or by specifying a file-type extension such as .json).
When the action is called, Merb first checks if the content-type requested is available (and throws an error if it is not). When render @users is called, Merb first looks for index.json.erb (if, for instance, JSON is requested). If a template is not found, Merb calls @users.to_json. So in this example, you would simply provide an index.html.erb, and let Merb call @users.to_xml and @users.to_json for the other content-types.
No more messing around with respond_to; the framework handles all the content-type negotiation for you!
While you're at it, feel free to take a look at my Why Merb? document, which goes into more depth about the architecture of Merb, and why you should use it!
That's a fair roundup of some of the coolest new features in Merb 0.4, and there's more to come on both my blog and others in the days to come. Enjoy!