Nov 24 2006

CakePHP vs Ruby On Rails

Category: Software DevelopmentDmitry @ 3:37 am

CakePHP is a MVC (Model-View-Controller pattern) framework that tries to mimic the way RoR (Ruby on Rails) does things. After developing a large web application on CakePHP platform, I decided to write a little bit about it and compare it the real thing. Haha, as you can tell, I am just a little bit slightly biased towards Ruby.Being a ruby programmer, and having to make a web app that uses php+mysql I immediately started looking for something similar to Rails. There are many rails-like frameworks for php, and I ended up narrowing down my search to cakephp and symfony. Because my client specified php4 (symphony only works on php5), I went with Cake.Scaffolder

Cake is a mature MVC framework with a large user base, excellent tutorials and API documentation. Scaffolder is a tool that generates website forms and pages for you, by looking at your Database schema. Most web MVC frameworks have a scaffolding feature and they typically generate add, edit, delete, and list functionality. This lets you quickly get things up and running.The very first step in scaffolding is generating a "model". A Model (M in MVC pattern) is an object representation of your sql table. Thats too vague ... what does it all mean? Well, if its in PHP, then you might have a Person class (that inherits from AppModel) that is bound to "people" table.

PHP:
  1. class Person extends AppModel {var $name = 'Person';}

Or in RoR, you have a Person class (that inherits from ActiveRecord::Base) that is bound to "people" table:

RUBY:
  1. class Person <ActiveRecord::Baseend

In the second step, you tell the scaffolder how your models are related. Some of the relations could be described as:

  • A has_many B (Person has multiple email addresses)
  • C belongs_to D (email address belongs to a person)
  • E has_and_belongs_to_many G (E permission has and belongs to many G Roles)
  • X has_one Y (wife has one husband, vise versa)

In cake, the scaffolder is in 'cake/cake/scripts/bake.php', and in RoR there is 'scripts/generate'. Cake's scaffolder is more interactive, as in it asks questions while it runs. It understands relationships between models. The RoR scaffolder is also a command line tool that takes a bunch of arguements and don't really asks any questions when it runs. The default RoR scaffolder is simplistic and doesn't generate pulldown menus ... etc, for models that are related to each other. Cake's default scaffolder does.

For instance, if you people and emails table, it will generate a pull-down menu of people inside emails add and edit screens. There are many scaffolders available for RoR, that generate pretty views and know how to handle complex relationships. RoR is way more comprehensive than cake, especially when it comes to scaffolding. One of the "alternative" scaffolders you can get for RoR is AjaxScaffold.

Model (ActiveRecord vs ... nothing?)

In web MVC frameworks, a model typically is an implementation of "Active Record" pattern. Ruby's ActiveRecord gem (package) is an object to database table mapping, kind of like DataTable in ADO.NET (yuck!). For instance, Person class is mapped to people table. You can access person.emails, delete a person with person.destroy ... etc, set a person's name with person.first_name = 'Dmitry', person.save.

RUBY:
  1. # code-block way of creating a 'person'
  2.  
  3. person = Person.new do |p| p.first_name = "David" p.occupation = "Code Artist" end
  4.  
  5. # cooler example
  6.  
  7. person.categories.find_or_create_by_name("Climbers")

Here some more examples

RUBY:
  1. # find me by fname and state. notice that parenthesis to a function call are optional!Person.find_by_last_name_and_city 'Dmitry', 'Spokane'# the next two lines give the same resultPerson.find_by_user_name(user_name)Person.find(:first, ["user_name = ?", user_name])

find_by_[...] is Ruby magic, because we don't actually define a function 'find_by_last_name_and_city()'. Its called dynamic, attribute-based finders.In PHP you can't do any of it.

CakePHP is a very ambitious attempt to implement Rails in an inferior language. Well, actually there is a find_by() function in Cake too that supposed to mimic ActiveRecord's, but, of course, its a hack job. To compare the two, look at RoR API's and CakePHP's APIs and you'll see for yourself.My biggest disappointment about CakePHP is its Active Record implementation: there isn't any! In Cake, you simply retrieve a hash, modify it, then throw it back to a function (or set it as $this->data) that actually saves it. So, there isn't a real binding between an object and a database table. The 'Person' object in Cake is not persistant.

The model class AppModel simply provides "macros" for dealing with SQL, instead of a powerful relational mapping that is found in Ruby's ActiveRecord. Here is a snippet from php5 implementation of Model's save function:

PHP:
  1. # save() function for php5# ...foreach($this->data as $n => $v) {if (isset($weHaveMulti) && isset($v[$n]) && $count> 0 && count($this->hasAndBelongsToMany)> 0) {$joined[] = $v;} else {if ($n === $this->name) {foreach($v as $x => $y) {if ($this->hasField($x) && ($whitelist && in_array($x, $fieldList) || !$whitelist)) {$fields[] = $x;$values[] = $y;if ($x == $this->primaryKey && !empty($y)) {$newID = $y;}}}}}$count++;# ...

Validation

Validation on Cake is done with regexp in 'cake/lib/validate.php':

PHP:
  1. /*** Not empty.*/define('VALID_NOT_EMPTY', '/.+/');/*** Numbers [0-9] only.*/define('VALID_NUMBER', '/^[0-9]+$/');/*** A valid email address.*/define('VALID_EMAIL', '/\\A(?:^([a-z0-9][a-z0-9_\\-\\.\\+]*)@([a-z0-9][a-z0-9\\.\\-]{0,63}\\.(com|org|net|biz|info|name|net|pro|aero|coop|museum|[a-z]{2,4}))$)\\z/i');/*** A valid year (1000-2999).*/define('VALID_YEAR', '/^[12][0-9]{3}$/');

I needed email to be valid, not empty and unique (in RoR is validates_uniqueness_of). I was surprised not to find it.

My Conclusion

  • Use the real thing: Ruby On Rails!
  • If using php is a requirement, CakePHP is better then nothing (doing it "by hand" with PEAR/Smarty).

Further Reading:

32 Responses to “CakePHP vs Ruby On Rails”

  1. roman says:

    just a quick question: did you actually check cakephp's php5 implementation of activerecord? its still not as nice as it would be possible with php5, but at least a lot better than the php4 version...

  2. Dmitry says:

    thanks for the tip, I'll look into it

  3. max says:

    There's better ActiveRecord implementation in the Akelos framework.

    at http://www.akelos.org

    check it out.

  4. diyana says:

    can i ask u the comparison between cakephp and ROR..
    actually i never use ROR b4 this..even the Ruby language i never heard b4 this..
    for ur info, i'd assigned to develop e-portfolio system and the system has to complete within 6 month..for those who never learned ruby & ROR, is it possible to use the ROR to develop the system?which one is better?cakephp or ROR based on my situation.

  5. Dmitry says:

    Hello Diyana, I though this was a comparison between RoR and Cake :)
    In any case, for you to develop a project within 6 months depends completely on your abilities. Everything is possible. As you can see from this article, there is no such simple answer as "better". Whats better is what suits you the best. For more info see "further reading" section
    -Dmitry

  6. cws says:

    I set up rails on a debian machine with apache 2.
    I found that whenever I modify the code except views, I should reload apache2 to see the changes like JSP applications.
    How do ruby hosting service providers manage this reloading requirement? Or is there any bypass I missed?

  7. Michael W says:

    I found that whenever I modify the code except views, I should reload apache2 to see the changes like JSP applications.
    How do ruby hosting service providers manage this reloading requirement? Or is there any bypass I missed?
    Maybe you can develop with RoR's built-in web server web-brick in the development mode which doen't cache / precompile your files...
    (but maybe that's not possible because in order to use it with Apache you change some of the scripts/fcgi-files etc... dunno, am no expert, just a hint! :) )

  8. diyana says:

    thanks Dmitry..
    i've tried the ROR..it seem's like very easy to learn n use. i just need few hours to learned the ROR.
    but i've not yet try the cakephp because the cakephp set up is not easy for me to understand.
    besides, the documentation is not clear and not detail as ROR.can u teach how to set up cakephp?
    and one more thing, in what way or criteria that i have to use to evaluate the framework?

    regards,
    diyana

  9. 空间 says:

    RoR rocks!

  10. Dave says:

    Sorry, but I've been using PHP so much longer that it makes little sense to put all my time into Ruby just to get some puny features out of it. Cake is close enough and PHP is extensive enough that I've been able to work faster and more efficiently in CakePHP. Yes, RoR boasts some good features, but the advantages of learning yet another language aren't great enough to move away from PHP.

  11. Zubin says:

    Dave:
    I've been a PHP coder for almost 10 years (since early PHP 3) and recently made the switch to RoR.

    Yes, it did seem pointless and a little daunting to ditch PHP and start again with Ruby but, after making the switch a year ago, it was well worth it. Why? Because Ruby is more powerful, easier to read and fun to code. And easy to learn!

    After all this time, I still have to check the argument order for many PHP commands (eg usually it's command([needle], [haystack]) except sometimes it's the other way round). PHP requires a lot of memorising, whereas Ruby does not (well, much less anyway!)

    Ruby has a lot more to offer than "puny features" - give it a go!

  12. Muhammad Hassan says:

    Thank you for this nice article,
    I like both cakephp and Rails.
    Did any one tried symphony ?

  13. Muhammad Hassan says:

    If any any one has a comparison between cakephp and symphony it would be great

    http://www.badrit.com

  14. Web App: Juvely » Ruby, ruby, ruby, ruby says:

    [...] So what are we going to do about it? Well at the moment not much, we have got well over 150kb of CakePHP code and I don’t really feel like rewriting it all just yet. We shall wait and say if any major problems crop up, and if so give that big task of rewriting a go. Although it might sound bad, I shouldn’t think it would take too long as getting the views right is always the biggest challenge when implementing a new feature! If you are interested more about how CakePHP stacks up, here is a good comparison! [...]

  15. Julia says:

    Thanks for the great work! It really is more than what was expected. I loved its simplicity! Keep up the good work!

  16. Henrique says:

    Hmmm... let me guess, you are a Mac user right? I can feel the hype ;)

    CakePHP is doing a great job as a framework alone - not being a Rails clone. The following 1.2 release will come with features that Rails doesnt have neither plans to implement.

    Also, design patterns are not copyright of Ruby On Rails. MVC, ActiveRecord, Scafolding... So, now if a framework implements this, its 'another Rails clone'? Shhh...

  17. Watts says:

    Um, Henrique, CakePHP was very explicitly inspired by Rails. It's not a feature-for-feature clone, no. But having used both (in fact, I have a lot more experience with Cake, since I'm using it on a professional project currently), there are a lot of things in Rails that are not there in Cake and a lot of what *is* there in both is done more elegantly in Rails. And there's not a whole lot that one can point to in Cake that's done more elegantly there than Rails, or that's exclusive to Cake that doesn't exist in Rails.

    A lot of self-appointed Rails "critics" knock down arguments that nobody in the Rails community, as far as I can see, ever really makes (i.e., the idea that Rails somehow invented Active Record or MVC design patterns, or the concept of scaffolding). Rails certainly has its drawbacks, but most of the ones I can see -- a sublime ignorance of all but the most basic features of an SQL database (no real concept of foreign keys, and rather egregiously, no way to use prepared statements), and an extremely rigid "follow our conventions or we'll make your life miserable" mentality -- are ones Cake shares. (Cake's database handling is, if anything, considerably more brain-damaged than Rails' is, from what I can see: it has no concept of "lazy loading," and it's quite possible to create a scenario where you're trying to get a 'table of contents' listing from one table but, because of associations, Cake will by default load in pretty much the whole damn database..)

  18. Dahito says:

    [watts]
    Cake's database handling is, if anything, considerably more brain-damaged than Rails' is, from what I can see: it has no concept of "lazy loading," and it's quite possible to create a scenario where you're trying to get a 'table of contents' listing from one table but, because of associations, Cake will by default load in pretty much the whole damn database..
    [/watts]

    Actually you can set the recursion in data retrieving, and unbind model if necessary. You can make your own query, set foreign key, use transactions .... etc... Of course you have to know the framework you're using to get the best from it, and here i think the cake docs and api lack something. Often i had to look directly into the code to learn/understand ...!!

    Anyway ... the 1.2 version is a big update and have lots of features... :)

  19. The Woodwork » Blog Archive » Ruby, Photography, and Women says:

    [...] Now that the Ruby developers are back from summer break, maybe I can get some of them to angry enough to tell me how I would have “totally nailed those two English chicks” if I had used Rails instead of PHP: “I’m sure you could have wowed them into a night of late static binding if only you could show them how elegant your Active Record implement(ation) is.” [...]

  20. Best says:

    Thanks for this great explaination this helped me make a choice between the frameworks.

    regards,
    Best

  21. Marton Sari says:

    "then through it back to a function"

    isn't it supposed to be "then throw it back to a function" ?

  22. Daniel says:

    Both frameworks works ok...

    Feel free to use what you want...

  23. AntonioCS says:

    On the blog post:
    "find_by_[...] is Ruby magic, because we don't actually define a function 'find_by_last_name_and_city()'. Its called dynamic, attribute-based finders.In PHP you can't do any of it"

    You can't directly do something like that but I believe you can do something like that using the magic method __call()

    From the manual:
    "The magic method __call() allows to capture invocation of non existing methods. That way __call() can be used to implement user defined method handling that depends on the name of the actual method being called."

    I work with php but don't use the CakePHP framework (or any framework for that matter) but I just wanted to set this straight ;)

  24. saurabh purnaye says:
  25. Aeshan says:

    Hi Dmitry,
    Nice article on RoR vs Cake.I'm also in a similar situation to some of the folks above, but my concern at present is not the learning curve (ive worked with cakephp for about 5 months) but availablity of RoR servers.For the sake of portability , is RoR as competitive as LAMP Cake in this regard?
    Thanks!

  26. Michael Hendrickx says:

    Being a PHP coder, I also switched to RoR.. the frustrating thing, to me, is the absence of backward compatibility.
    The little of documentation that you do find on RoR, is often for Rails 1.2, and doesn't work on 2.0.

    Dynamic languages and all is nice, but come with a price (performance).

    I'm migrating apps back to PHP (therefor not cake for that matters), but surely RoR tought me how to program things the correct way.

  27. Wiras Adi says:

    One thing to be noticed is that it's not easy to find a (cheap) good Rails hosting out there. For production, Rails apps need to run using Mongrel or FastCGI. Otherwise it is incredibly slooowww.......

  28. dude says:

    Wiras raised a good point, does anyone know about the performance coparisson between the 2?
    I worked php most times but in recent projects i've done cakephp due to client specs, i noticed it very slow at times but i never tried ruby so not sure if its good for very processing intensive large apps
    thanks

  29. Straw Dogs » Rails Alternatives says:

    [...] Rails vs. CakePHP Comparison [...]

  30. Greg says:

    @Wiras

    RoR is not nearly as complicated/expensive to host now as it was a couple of years ago. One of the easiest ways to run Ror is to use Litespeed (www.litespeedtech.com) on a cheap VPS like Slicehost. Their ruby gem makes running RoR apps a piece of cake (pun intended) :)

    Cheers

  31. Mike says:

    I choose CakePHP over ROR because PHP has the MySQL interface as an integral part of the language. I couldn't get ROR to access MySQL on my Linux+Apache machine because the MySQL interface comes from another source than the Ruby. Ruby is a nice language, but until Ruby has the MySQL interface built-in, I'll stick to PHP.

  32. deltawing says:

    I don't understand the religiosity involved with what are just merely tools that are used to realize a design.

    There are reasons why someone would choose CakePHP and why someone would choose Rails.

    Besides, since CakePHP is a close clone of Rails if you know one then you pretty much know the other.

    Suggested reading: Patterns of Enterprise Architectures by Fowler. It gives a coverage of "architectures" and "patterns" without specifying any particular language.

Leave a Reply