UPDATE: This blog post was written in April 2008, I moved to Rails full-time shortly afterwards, but as I’m moving to a new blog engine and this is a huge part of my history I wanted to keep it
I’ve been a PHP developer since 1999, am currently a Zend Certified Engineer for PHP4 and PHP5 and work as a contractor for a large media company developing systems in Symfony. While Symfony is an excellent PHP framework (it takes a lot of inspiration from Rails), there are some things that make it less than perfect when compared with something like Rails. I decided to pick a new skill to learn this year as an investment in my future. Out of all the new frameworks, I decided to look at Rails because it seemed to have most of the hype (don’t get me wrong, frameworks such as Django have excellent potential, but I went with the one most people were talking about).
After doing a bit of reading about what makes Rails so popular/hyped I found it irresistable! I’ve listed below some of the cool things that Rails does/makes easy and these together describe why I think Ruby on Rails is an idea web development environment, combining a lot of best practices in to one easy to use package.
This article isn’t aimed at non-technical users, nor is it aimed at experienced Rails developers. To be honest, it’s not really aimed at anyone — it’s purely a collection of my thoughts that someone may find interesting.
UPDATE: Having read (and replied to) a long blog post about how I’ve given Symfony a short-shrift, I’d like to explain. This isn’t a list of what Rails has above Symfony. It’s a list of what makes Rails cool. I know Symfony has some/a lot of them. Some are done better by Rails, some are equal (I don’t actually think Symfony beats Rails in any of them). This is purely my list of reasons why I think Rails has everything a professional web developer needs, particularly in comparison to a non-framework development methodology (I still have 4 legacy sites I work on that aren’t even Symfony-based and are too large to migrate easily). [17 April 2008]. For Web development services visit Vivid Designs
1. MVC Design Pattern This is a Design Pattern that helps in deciding where to put sections/layers of your code. Sure, you can be this organised without a framework to enforce a design upon where you put your code, but it helps to have it all decided in a generally accepted manner. The separation layers in MVC also aid with testing each layer separately. Symfony has a similar separation, but the model layer of Active Record in Rails is much better than Symfony’s default of Propel.
2. Helpers The idea of keeping your business logic completely separate from your presentation code is a great idea, but it’s not always that easy. Therefore there is a need for something called Helpers, which are logic code that can be called from your presentation/template code. Again Symfony has these too, but the difference that makes them nice in Rails is that it automatically creates application and controller level Helper files and automatically makes the methods available in either all templates or those for that controller.
3. Integrated Testing Framework Test-Driven Development is becoming more and more popular and recently I’ve either been doing TDD or at least automated testing after the fact. I don’t advocate taking it as far as The Book (I can’t ever see the point in writing code that I know will not stay in the codebase, which is what is advocated by “only write the barest minimum code to get the test to pass”). Rails has a ready integrated system for testing. This includes fixtures and it’s own environment (more on that later).
4. Easy Enhancements to Active Record Models This is really a feature of Ruby more than Rails, but it’s so easy to enhance a model with an extension — it’s normally just a matter of installing the plugin and then adding a single line at the top of the model file. It’s equally easy to add validation to a model (no defining methods that are called, just add the line which adds the validation at the top of the model).
5. Built-in Development Web Server For someone new to a given development environment/web programming language it can be difficult to set up the web server environment (installing Apache, PHP, activating the module, etc). After initiating a new rails project, running a web server to get started with development is as simple as running console/server.
6. Console for Quick Testing Ruby has an excellent console for quickly interactively running Ruby code. PHP has this too now with the “-a” flag to the CLI binary. The nice thing about Rails is that it has a script called console/server that runs IRB but loads Rails’ class loader so all of your model files are ready to be used.
7. DB Migrations One of the traditional problems of web development (at least for small shops that haven’t built a solution to this) is how to keep the structure of your database a) consistent between development and live servers and b) stored up to date with the code version it relates to in a version control system. Rails makes this easy with a system called Migrations. Basically, each is a numbered script that lists the database changes to take the schema state up to this version or down from this version. When running the migrations it creates a table in your database to store the current version number and updates this table after running migrations. Bringing your production environm ent up to date is as easy as running a single command (or Capistrano task, but more on that later).
8. Environments Even small development shops and one-man bands don’t normally develop code directly on the live server. With Rails there is a concept within the framework of environments, each having potentially different settings (e.g. Merchant account settings, logging level, etc) and database configuration. By default it comes with development, production and test (for not whacking your dev or prod database with test data when running automated tests). It’s also easy to add your own custom environments (such as staging for a proofing version of the latest code). For Best Website development services in Chennai visit Vivid Designs
9. Session Stores In the old days (PHP unless you write a custom session handler), session data used to be stored in flat files. Rails has this option but the problem with it is if you have multiple load-balanced servers, the session data is only stored on the machine it’s used on. If that server goes down (or the user gets sent by the proxy/load balancer to a different server next time) they lose their session. This then brought the idea of sticky sessions, where the p/lb will continue to send a particular connection to a particular backend once they’ve been sent there once. Rails has better answers in the form of a Database-backed session and a pure-cookie session. The former is obvious, the database is shared so it’s a good place to put shared session data, available to all backend servers. The latter means storing the session data in its entirety in the client’s browser via a cookie. This can be very useful, but it’s important to remember that it means that the user can read the cookie data (although it’s protected with a cryptographic hash from being changed).
10. RESTful Resources In traditional development there are two HTTP Methods used: GET and POST. Links are GET and forms are (usually) POST. However, HTTP defines more methods than that (such as PUT and DELETE) and there is a ‘new’ philosophy that uses all the verbs to change the state of a given resource on the server. This mechanism is called REST and it requires a bit of a change in thinking (rather than pages, you think in terms of resources). Rails makes it nice and easy to create RESTful web sites (and therefore easy RESTful web services) using its Routing system.
If a site adheres to Rails’ idea of what a RESTful service should look like (using the full range of HTTP verbs, XML output) then there is also a nice class called ActiveResource that you can subclass to effectively treat a remote RESTful service as a local database table. This makes inter-site communication a breeze (at least between two Rails sites)
11. Multiple Response Formats There is an easy construct in a Controller method to state that you will respond to many format requests (e.g. /blog/show/1.html and /blog/show/1.xml) and will use a different template for each. You can even use filters to change the format requested even if it was the same (e.g. you could return an iPhone specific templated version of a page if their HTTP User Agent contained ‘Mobile Safari’). This makes it very easy to have different versions of your site for different target devices (particularly as the view contains no business logic).
12. Custom Command-line Tasks Rails uses ‘Rake’ tasks to automate many things (such as migrating databases described above). Rake tasks are basically snippets of Ruby code and you can write your own. This means if you have a common task after deploying your site (such as pinging a service to notify them of the new version) you can easily write a custom task and run it using something like rake mySite:myTask
13. Automated Deployment to Multiple Servers There is a relatively new deployment utility called Capistrano that you can basically use to check out code (from a VCS) on to multiple servers and running Rake tasks before/after over SSH. This makes deploying your code to multiple backend servers very easy as you have the holy grail of a ‘one-click build script’ in a web-deployment form.
14. Installing to Apache This isn’t really what’s cool about Rails, but I wanted to give it a mention. One of the things in the past that made me wary of learning Ruby on Rails was that you had to do some server voodoo to get it to work with Apache (e.g. set up a ‘Mongrel’ cluster and have Apache proxy requests through to this cluster). This concern has been removed recently with the release of Phusion Passenger. According to the screencast (by the Railscasts guy) it’s very easy to install although I haven’t given it a go yet.
UPDATE: I now have installed Passenger and it’s VERY easy to install. I’ve configured a virtual host for a site I’m going to be launching and another one for the staging version and both work great.
15. Filters Often you need to make a section of your site password-protected or log all access to it, or some other requirement. In PHP you’d end up calling a function at the top of each page (or putting it in the header template if you use one). Rails has a better way, you can choose to run custom filter functions before/after or wrapped around controller actions (either all, optionally excluding some, or those specified).
This means that protecting a controller from public access is very easy and less likely to be prone to new actions/pages being accidentally left unprotected.
16. Non-GUI Debugging Support Although it would be nice to have integrated debugging with TextMate (my editor of choice on the Mac), that isn’t currently a reality. However, it is very nice that you can simply add a line of code anywhere in your application and have the script/server break in to an interactive prompt to enable you to examine/change variables, call methods, or step through the code from that point.
17. Running Cron Jobs Although there is no built in support for running jobs at a certain time within Rails (there are plugins to be able to perform timed or forked processes) there is a script called script/runner that will enable you to run a method on a class from the command line (and therefore also from a cron job).
18. Benchmarking/Profiling I love performance tweaking. I’d say this is probably my favourite area of development; taking a slow-ass site and making it run like greased lightning! Rails seems to have many ways of testing the performance of your application, indeed the standard development server’s stdout shows a projected number of requests/second that it could perform and the amount of time spent in DB calls.
The two main tools Rails provides for performance testing though are in the script/performance/ folder: benchmarker and profiler. Between them, these two scripts can either run an action through a series of requests to get statistics on actual performance (rather than just projected estimates from the log) and profile how the code is running internally with breakdown of time spent in each function and number of calls made.
19. Flash Variables A very simple feature is called Flash Variables. This is simply an easy way of storing a message (or any value, but messages are most common) to be displayed to the user on the next request only. This is commonly used for validation errors or success notifications. Of course, it’s easy enough to have your display code in PHP display a session variable if it’s set and blank it afterwards, this is just indicative of the nice touches that the Rails Core Team have put in place because they know what’s common in web applications.
20. Integrated Caching Rails includes (at least) three different ways of caching content in order to speed up subsequent application requests. It can cache whole actions (including the layout), part of an action or any block of code’s output. Rails often has a reputation for not scaling well and caching is one easy way to scale applications. For my 2p-worth, I don’t think that reputation is particularly deserved now, but as hardware is cheap and the architecture is built to be load balanced between machines with a decent session storage mechanism I don’t think it’s as big a deal as others do.