Why I Prefer Ruby on Rails over CakePHP

Last year, I had a goal to learn Ruby on Rails and build an application in that framework. By learning CakePHP, I was able to wrap my mind around the rails framework concepts and make that transition a little easier. This year, I have made the full plunge into the Ruby on Rails, and I absolutely love it. As I’ve made the transition from php to ruby and from CakePHP to Ruby On Rails, I’ve written down some of the reasons why I now use Ruby on Rails over CakePHP.

[note: I still prefer to use CakePHP over no framework if a client requests an application be written in php. However, when we have the option to start the project in Rails, we really push for rails.]

Here are some of the reasons why I prefer Ruby on Rails over CakePHP:

Rails doesn’t require you to grab all of your data in the controller

When working with CakePHP, you must retrieve all of your data from the database in the controller and pass it all to your View. All of this data is stored in an associative, which makes accessing your data very easy, but lacks the functionality of using an object.

All of the data that you will need from associated models must exist in the array(s) that you pass to your view. You can grab data from associated models this by using Cake’s recursive option which will grab all of the data in surrounding models.

Lets say that you have an Author that has many Articles, Articles have many Comments and you would like to grab the Author, her articles, and comments to give to the view. You would do this with the recursive option of 2 levels of data retrieval. However, lets say that the author also has many books and books have many chapters. When you do a recursive find on the author, it will grab all of the articles and comments, books and chapters. This leads to a lot of wasted data retrieval

With Rails, you can easily walk through the data models while your are in the view, and if the object doesn’t yet have that data, it will automatically query the database behind the scenes. This is a beautiful thing. So, in the controller, you only have to grab the author. In the view you can then walk the model in the following way:


Of course you can iterate through the articles and the comments, but you can continue to move to associated models all you want. Also, to save queries to the database, you can do an eager find and specify that you also want her articles so that the articles are also returned in that first query. That is super powerful!

Rails model objects allow for dynamic attributes

Lets say that you have a User model that has the attributes of a first_name, and last_name. When displaying this information, you often want to show the full name. You might just output the first name then the last name every time, but wouldn’t it be nice if you just had a full_name attribute? In rails you can do this by defining a new method named full_name on the User model which returns the formatted full name. In Cake you can’t do this because you only have an associative array.

Lets say that the users have an image associated with their record. The image path on the server can be derived by their user id and an image extension which is stored in the users table. The path would be /images/users/[id].[image_extension]. In Rails, you can define a method on the User model named image_location which returns the formatted path. In Cake, you would have to formulate the path inside the view every time you wish to display it.

Further, if the user had no image, you can check for that inside your image_location method for the image_extension and return a no_image.gif when appropriate. In Cake, you would have to wrap some logic around your image display inside your view which makes it much uglier and prone to bugs.

Rails Has Superior Url Routing

[UPDATE: Ben has just notified me that Cake has now added similar routing capabilities. See his comment.]

Rails has amazing routing capabilities. At first glance, it appears that Cake can do everything that Rails can do, but it can’t. One of the main differences is that Cake’s routing is a one-way routing. Another difference is the way that Cake handles parameters passed to the controller.

One-way routing

Cake’s routing is one way, meaning that you set up your routes in the configuration, and then you must remember your url structure and write the urls yourself throughout the application.

For example, if you are building a social application which features personal profiles. You decide to name your controller ‘Person’ and the action to view the profile ‘view’. Each person is identified by a unique id, so you decide to use the default routing in cake and rails which would give you a url of /person/view/33 for person #33.

Throughout your Rails application, you’ve linked to the personal profile pages by calling link_to(persons_name, :controller => 'person, :action => 'view', :id => persons_id). This builds a url using the default route /person/view/[id].

Throughout your Cake application, you’ve linked to the personal profile pages by calling echo $html->link($persons_name, "/person/view/".$persons_id); . This also gives you the same url: /person/view/[id].

Down the road, you realize that you would like to make your urls more friendly, and represent personal profile pages with a url like: /friend/[id].

In rails, your new route looks like this:

map.connect "friend/:id", :controller => 'person', :action => 'view'

In cake, your new route looks like this:

$Route->connect('/friend/*', array('controller' => 'person', 'action' => 'view'));

It appears that Cake can do everything that Rails can do, but what about all of your urls that you have scattered throughout your application. Rails will automatically write them to fit this new routing pattern. Cake makes you find all of your links and change them by hand.

Rails has two-way routing, where Cake’s routing is one-way.

Parameter handling

[Correction here: You can accomplish similar parameter handling capabilities with Cake. This becomes a null point. You can still concatenate a querystring to the end of the url and use $this->params[‘url’][‘param_name’] to retrieve your parameters].

Cake handles parameters on the url differently than rails. With Cake, your parameters are listed like so /find-person/[param1]/[param2]/[param3]/[etc.].

In your Cake controller, you accept the parameters like so:

function find_person($name, $city, $page)

The order in which they appear on the url determines which parameter they become in the action.

Rails checks to see if the parameter matches a url definition in its routes, and if it doesn’t fit there, it will append it to the end of the url in a querystring like so: /find-person/?name=x&city=Provo&page=3.

In your Rails controller, you would access the paramters like so:

def find_person
name = params[:name]
city = params[:city]
page = params[:page]

You might think that Cake’s way of handling the parameters is superior because it keeps the url looking prettier. However, this can be a real pain if you are writing an advanced search where any of your parameters can be optional. It’s also nice to be able to use a form with the method=GET for search. I don’t know of a way to do this in Cake. See the above message on how to do this in Cake.

There are still other reasons for using Rails over CakePHP, and there are some reasons why clients will still prefer to stick to php. What are some of the reasons you prefer CakePHP over Rails or Rails over CakePHP?

Picking up Ruby on Rails after CakePHP

So, I’m finally diving into Ruby on Rails. The transition to Ruby on Rails from using CakePHP is going fairly smoothly. Now that I am really comfortable with the MVC framework that CakePHP uses, the learning curve has been pretty minimal.

My web hosting provider offers Ruby on Rails support, but I don’t like editing files directly on a server, so I decided to get things running locally on my own machine. It has been kind of a headache to get things working with FastCgi. Without FastCgi, everything runs pretty slow. With fcgi support, it runs really fast, which is nice. Just remember that you must restart Apache after you change your database.yml file.

If you want to start developing on Rails, I suggest following the WARR (Windows Apache Ruby on Rails) setup instructions. These instructions finally got my fcgi to work. You don’t have to put things in the directories that the tutorial suggests, especially if you are already set up with apache, mysql, etc.

If you want to learn some of the basics on Ruby, I suggest the following sites:

  • Try Ruby – This site lets you type ruby commands into a little console in the browser window. No installation needed, just a browser. Follow their tutorial! It gives a pretty good, quick run-through of Ruby programming principles.
  • Why’s (Poignant) Guide to Ruby – This is an online book that is an easy read.

If you’re looking for some good Rails tutorials check out:

If you really want a good understanding of Ruby on Rails, and Ruby, I suggest buying these books:

  • Agile Web Development with Rails – This is a good book whether you’re learning Rails or another inspired framework such as CakePHP. It was written by David Heinemeier Hansson, who is one of the master minds behind Rails and is on the 37Signals team. All parts of the MVC framework are discussed thoroughly in this book, and it has the best explanations for Model relationships such as Belongs To, Has One, Has and Belongs To Many. This book is awesome.
  • Programming Ruby – This is an in depth guide to Ruby programming. It covers the basics all the way to the advanced features such as distributing Ruby objects across several processes and servers, much like Java’s RMI or CORBA. It is written by Dave Thomas (not the Wendy’s guy) who is also a co-author of the Agile Web Development with Rails book.

So, now I’m off and running, or at least jogging, with Ruby on Rails. Ruby is a really cool programming language. A lot of stuff seems backwards from what I’m used to with languages such as Java or php, but the differences actually make Ruby super elegant. It will take me a while to become super proficient in it, but I’m on my way.

I’ve already noticed some differences between Ruby on Rails and CakePHP, which I’m taking note of. I’ll write again soon with a detailed comparison of CakePHP and Ruby on Rails.

Why I use CakePHP over Ruby on Rails

[Update for all visitors: I’ve written a new post name Why I Prefer Ruby on Rails over CakePHP. Please visit that for a more up to date opinion.]

In response to Blake’s question on my last post “Why I Like CakePHP”, the main reason is that I still use CakePHP over Ruby on Rails is availability of php programmers. It’s a lot easier to find someone who does php than it is to find someone who does Ruby.

Also, if we are building projects that will eventually be deployed on a client’s server, the client will eventually need to maintain it. It is easier for them to support a php solution over a Ruby on Rails solution because because they will find more people familiar with php than ruby.

For a comparison of language popularity, although I realize this doesn’t say it all, here is a Google Trends chart comparing php with ruby.

PHP, Ruby comparison

PHP is in blue, and Ruby is in red.

Now I admit that Ruby on Rails is a superior product over CakePHP. Rails was built for a language like Ruby, not for php. However, php does a good enough job with handling the Rails-like MVC framework. All that said, I wish Ruby was more popular because it would be fun to jump into.

It seems that a lot of the php community, including myself, have become very framework-centric. I think this stems from frustrating hours/days/weeks of digging through spaghetti code, trying to debug php applications.

Because of the immense popularity of php, I think one of the php MVC frameworks will catch fire and surpass Rails in popularity.

Why I like CakePHP

A couple of months ago I began investigating php frameworks to see if I could improve my efficiency in developing rich web sites. I had tinkered with Ruby on Rails, but I didn’t have the time to learn a new framework and a new language at the same time. I realized that if I was going to make a good use of my time, I needed to begin using a framework in a language that I already knew.

I began looking at the different php frameworks and found this post on h3rald.com comparing Rails inspired frameworks. His article also points framework-seekers towards some other good frameworks such as Symfony, PHP on Trax, Code Igniter, Biscuit, and Live Pipe. I was most interested in CakePHP and Code Igniter, although PHP on Trax also caught my attention.

I decided to go with Cake, because it uses the MIT lisence and appeared to have the largest userbase. Cake’s Google Groups discussions appeared to be pretty active so I knew I could get support if I needed it. I had also read some other posts by web-guru Jonathan Snook and his experience with CakePHP. The only complaint that I saw from reading his blog was the lack of great documentation, otherwise he seemed pleased with the framework. So I decided to jump in.

My experience with CakePHP hasn’t been all roses. I’ve had my frustrations, mostly with lack of parameter details in the API documentation. However, the frustrations are far outweighed with all of the “Holy Cow!”s and “I can’t believe Cake already does that for me!”s. So, here are some of the reasons for Why I like CakePHP.

#1 – Cake’s Model does all of your CRUD for you

In past web projects, I had developed my own MVC web applications in which I would program by hand Data Access Objects. These objects would perform all of my Create Read Update and Delete operations, or CRUD operations. I always thought to myself that there had to be a better way. This always took forever to do, but it usually paid off in the end as it kept my database fairly decoupled from the rest of my applications.

Cake’s Model handles all CRUD operations automagically, and it does it well. All you have to do is define relationships between your models (or database tables). Although it might take a little while to understand the differences between belongsTo, hasOne, hasMany, and hasAndBelongsToMany relationships, there is a huge return on investment.

Some argue that the naming conventions are too restrictive, but I see it differently. I think it provides good structure for defining a schema as you work in a team. I have found the naming convention and relationship definitions to be a great asset. Reading the relationships between the tables provides good documentation on how your database schema is set up. You don’t have to spend lots of time trying to decipher someone else’s crazy SQL queries to figure out what’s going on.

#2 – Cake’s Scaffolding helps in prototyping

The faster you can get a client a prototype, the better off your project will be. CakePHP’s scaffolding provides just that. It allows you to set up your database model, define the relationships, and then automatically have screens listing records, providing create and edit forms, and record deletion capabilities. It even dynamically responds to changes made to the database. This has allowed us to check something off with a client, get quick change requests made, and then begin solidifying the project.

#3 – Cake makes building AJAX applications easy

CakePHP integrates very well with Prototype.js and Scriptaculous to help in creating rich internet applications very quickly. If you’ve never used Prototype.js, or Scriptaculous libraries, you are in for a treat. Prototype actually makes JavaScript programming fun. It abstracts browser-specific junk away from your code, so that you can get to the important code quickly. Scriptaculous integrates with Prototype to do awesome html animation effects. CakePHP provides ajax and javascript helper classes to help write the javascript code for you.

Helpful links to get you started: Prototype documentation, more Prototype documentation, Scriptaculous documentation, CakePHP AJAX Tutorial

#4 – Cake gives you pretty URLS

The CakePHP framework gives you a pretty url structure. Now you don’t have to waste time routing your mod-rewrites to your php scripts. Cake has a default url structure of {controller_name}/{action}/[{param1},{param2},etc.] . So, for example you might have a url of http://example.com/users/edit/1 which would bring you to your edit page for your user with id of 1. If you don’t like the structure, then you can use the routes config file to create custom routing.

#5 – Cake writes code for you with the bake script

Setting up your models, views, and controllers couldn’t be any easier. Cake provides a bake script that you run from the shell which builds your php files for you. It will even write the code that produces your scaffolds views, creates, and edits. This provides you with a starting ground from which to edit and customize from the scaffold. This saves you a ton of time, as you don’t have to start from scratch.

There are even more reasons for why I like CakePHP, but I’ll have to save those for another day.

CakePHP – a good transition into Ruby-on-Rails

About two months ago, I was introduced to CakePhp, a Ruby-on-Rails-inspired php framework. After studying the various rails-inspired php frameworks, I decided that Cake was the way to go. My experience has been great, although there have been some bumps along the road.
For almost a year, I had been wanting to dive into Ruby-on-Rails. I had successfully completed a few Rails tutorials, but, at the time I didn’t program in Ruby. Therefore the lines were blurred as to what was being done by Ruby and what was being done by Rails magic. CakePHP has provided a great transition for me, as I’ve been able to learn the framework without learning Ruby.

I have read most of Agile Web Development with Rails, and am now able to differentiate between the Rails work and the Ruby work. Ruby looks like a really fun language to learn, and I hear it is really powerful. I would love to jump into it fully now and reap the benefits of this beautiful framework.

I wouldn’t ever want to develop another site without a good php framework. CakePHP is a great framework to work with. However, it still isn’t as mature as Ruby-on-Rails, and doesn’t support all of the features that Rails does. That’s why I still want to jump into Ruby-on-Rails.