Like rats deserting the good ship Merb - introducing merb-to-rails3 railtie

John Cieslik-Bridgen by John Cieslik-Bridgen, 31 March 2010

This blog post isn't meant to be a Merb vs Rails discussion, fun though that can sometimes be – instead we'd like to publicise a small utility library that Marcin Kulik and Piotr Solnica have written to help you port a Merb application to Rails 3, by adding several methods from Merb's API to your Rails 3 app. The background to this gem is that Lunar Logic Polska have a mix of deployed applications, some Rails 2, some Merb, and also two distinct camps within the company – the Merb lovers, and those who have yet to try Merb...

Merb fans here pointed to better performance and higher productivity. An architecture that was extensible, that avoided "monkey patching", a clean API for plugin development. It's true to say that we have here a small, vocal Merb fanbase, and they have tended to evangelize enough to convert others along the way!

So whilst some of the team here at LLP are decidedly Merb converts, having looked at the current state of Rails 3 development against Merb, we decided that we would port all of our applications to Rails 3. It seems to us that there is now only very limited development of Merb, and whilst we have recently seen the Merb 1.1 release, this was something we'd been waiting for a year for. Just a few months ago the picture was quite different – but the beta release of Rails 3 changed the landscape dramatically, and prompted our decision. We think that Rails 3 is the future. Indeed, the release notes of Merb 1.1 write that whilst it is intended that Merb should have a future, it is not clear what that future is.

The merb-to-rails3 gem provides proxy methods for Views and Controllers to ease your migration from Merb to Rails 3:

Controller:

  • redirect => redirect_to
  • before => before_filter
  • after => after_filter

Controller/View:

  • url(name) => name_path
  • resource(...) => ....._path
  • submit => submit_tag
  • css_include_tag => stylesheet_link_tag
  • js_include_tag => javascript_include_tag
  • throw_content(name, ...) => content_for(name, ...)
  • partial => render :partial

The gem essentially provides a collection of helper methods that will allow you to get an application up and running, taking care of some of the most frequent exceptions you might encounter, logging warnings to the console that you can deal with at your leisure, and also suggesting alternatives for deprecated methods. Here's an example of console output:

The alternative to using our gem would be to generate a fresh Rails 3 application and deal with exceptions one at a time – but by providing proxy methods, we aim to at least have the core of a migrated application in a state where it can be worked on largely without exceptions.

This little gem also allows you to handle Merb-style controller exceptions (ie. raise Forbidden). You just need to add rescue_from MerbToRails3::ControllerExceptions::Base, :with => :my_handler to your ApplicationController. Like this, for example:

In an ideal world, the gem would be all that is needed, but in reality, manual intervention is still required in some instances, as some issues can't be resolved by proxying methods. For example, in deciding how to deal with Merb's behaviour whereby the return value of a controller is the response body returned to the browser. Such differences require human input, and we have intentionally required this, althought we did discuss a rake task that could run regexps over controllers, suggesting replacements as a possible future solution. Consider the example below, contrasting controller behaviour:

Another suggested enhancement would be to create a MerbController class, a subclass of Rails' AbstractController which would handle actions the Merb way – this could be set as a base class for your Application (controller). It could be argued of course that this is short-termism, as we wouldn't propose attempting to replace the Merb API in Rails 3. Also, whilst we considered converting Merb route definitions to Rails 3 routes, we haven't included that for now, as we decided that this was really a one-time, one-file task"

There are then some "nice-to-haves" that our gem doesn't provide – but as ever, we're busy, pragmatic people, who have to balance such decisions with the rest of our workloads! This is Open Source software, and we would encourage any contributions, but in the meantime, we hope that it will be a useful resource for other developers migrating from Merb to Rails 3.

How to set it up? Just add it to your app's Gemfile:

gem "merb-to-rails3"

and run:

bundle install

Check your scripts with JSLint on Rails

Jakub Suder by Jakub Suder, 29 March 2010

In 2009, I worked on two major projects at Lunar Logic Polska, HabitatMap and Hapnin. Both of these involved quite a lot of Javascript code – to such an extent that sometimes there was much more complexity and work involved on the Javascript side than on the Rails side.

When you write so much Javascript code, you need to start taking the language seriously and make sure that you follow the same kinds of best practices that you do with your Rails code – otherwise, your Javascript will quickly become unreadable and difficult to maintain, and the bug count will increase exponentially. In Hapnin, I used the Blue Ridge library, which combines a Javascript testing framework (Screw.Unit), mocking library (Smoke), Rhino and EnvJs (for testing in the console) in an easy to use Rails plugin.

There are however some specific kinds of errors that can be detected much easier, automatically, without having to write any unit tests, and which could be missed completely by the testing suite. Things like a comma at the end of a hash definition (e.g. { a: 1, b: 2, }) – this would pass any Blue Ridge spec, but would crash the site in Internet Explorer, or '==' operator used in a place where '===' is more appropriate – which you probably wouldn't find unless you knew what to look for.

Luckily, there is a tool that can find these kinds of errors, a tool that most web developers probably have heard about, but which few of them actually use. It's called JSLint and was written by Douglas Crockford 8 years ago.

I think one of the reasons why Rails developers don't use JSLint often – apart from not knowing about it, or not realizing that it can be useful – is that it isn't as easy to install and use as Rails testing frameworks like Test::Unit or RSpec. Instead of installing a gem or plugin and calling a rake task, you have to download and install it manually in the system, or use some other package manager like MacPorts.

I looked for any Ruby libraries that would wrap JSLint into something more convenient for a Rails developer, but I couldn't find any – so I've decided to write one. JSLint on Rails is a Rails plugin, and it contains everything you need to check your code with JSLint – JSLint itself, Rhino Javascript engine and some Rake tasks; the only thing you may need to install manually is Java JRE (required for running Rhino), but you probably already have that.

Here's how you use it:

  1. Make sure you have Java installed.
  2. Install the plugin: ./script/plugin install git://github.com/psionides/jslint_on_rails.git
  3. Run the rake task: rake jslint
  4. Optionally, add rake jslint to your continuous integration build to make sure it's run automatically.

When you call rake jslint, you will get a result like this (if everything goes well):

Running JSLint:

checking public/javascripts/Event.js... OK
checking public/javascripts/Map.js... OK
checking public/javascripts/Marker.js... OK
checking public/javascripts/Reports.js... OK

No JS errors found.

If something is wrong, you will get such results instead:

Running JSLint:

checking public/javascripts/Event.js... 2 errors:

Lint at line 24 character 15: Use '===' to compare with 'null'.
if (a == null && b == null) {

Lint at line 72 character 6: Extra comma.
},

checking public/javascripts/Marker.js... 1 error:

Lint at line 275 character 27: Missing radix parameter.
var x = parseInt(mapX);


Found 3 errors.
rake aborted!
JSLint test failed.

The plugin has also a configuration file, config/jslint.yml, which is created for you during the installation. You'll want to take a look at it, especially to change the “paths” and “exclude_paths” options that tell it which files to check – I'm pretty sure you don't want it to check entire jQuery or Prototype each time, just your own code. You can also set all JSLint options in that file – I've set the defaults to what I believed was reasonable, but feel free to tweak them if you disagree. I've also added a few custom options to silence some types of warnings which I find annoying – you'll find these at the end of the config file, disabled by default.

If you use a different Ruby web framework (e.g. Merb or Sinatra), or you just don't want to use Rails plugins for some reason, JSLint on Rails can also be used as a plain Ruby gem. To do that, you need to:

  1. Install the gem (gem install jslint_on_rails, or via bundler).
  2. Include JSLint's tasks in your Rakefile: require 'jslint/tasks'
  3. Also in the Rakefile, set path to your config file: JSLint.config_path = "config/jslint.yml" (anything you want actually)
  4. Create a sample config: rake jslint:copy_config

After that, you can update your config and run the test with rake jslint.


Our first iPhone app available on AppStore

Jakub Suder by Jakub Suder, 3 March 2010

I became interested in iPhone development last winter, when I bought my own iPhone. I wanted to learn how to write iPhone apps, and the best way to learn how to program is to do it – so I needed to write a first simple application, that I could learn and experiment on. I've decided to write an iPhone client for our RubyTime service; I figured it would save me a few minutes each day if I could enter my activity entries while waiting for a bus on a bus stop instead of doing it in a hurry in the office before I leave (of course, I could also do it using mobile Safari, but it wouldn't be as convenient… and it wouldn't be so fun!).

The first version was ready a few months later – it was able to display recent activities and add new ones. I used and extended the JSON API that Marcin Kulik has earlier created when he was working on his RubyTime plasmoid for KDE4. I showed the app to Paul and he liked it so much that he allowed me to spend almost a month of my working time on improving it and adding new features. I've added support for admin accounts, to let Paul check on his iPhone who was busy and who wasn't, and for client accounts, so that our clients who have iPhones can monitor the progress of their projects. I've also added a search form that finds activities within a certain time range for given projects and users.

It took a bit longer than expected to bring the application to the point when it can be publicly released, also because we had to make sure that potential users can download a stable version of the server that supports the client app; but the release finally happened last month. I was surprised how fast the application went through the review process – I had heard stories of apps waiting for weeks or months to get accepted; mine was ready in less than 3 days!

If you want to try it, iRubyTime is available on the AppStore for free. I've also shared the source code of the app on GitHub, so if you're learning Cocoa and iPhone SDK, you can take a look at it and use it as an example or starting point for your own projects.

I must say that working on your first iPhone application is very difficult at first. It's a completely different experience than working on a Rails webapp – partially because of the language (ObjC), but also because of different approach and paradigms used in mobile app development, and because of limitations of the phone's hardware. I had to fix hundreds of strange and confusing bugs – but that means I've also learned a lot, and it will be easier next time.

iRubyTime screenshot

© 2009 Lunar Logic Polska. All rights reserved.

Lunar Logic Polska is a proud member of:

Scrum Alliance Agile Alliance ITSBA