CakePHP vs Ruby On Rails
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.
-
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:
-
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.
-
# code-block way of creating a 'person'person = Person.new do |p|p.first_name = "David"p.occupation = "Code Artist"end# cooler exampleperson.categories.find_or_create_by_name("Climbers")
Here some more examples
-
# 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:
-
# 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++;# ...
ValidationValidation on Cake is done with regexp in 'cake/lib/validate.php':
-
/*** 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:
- Ruby On Rails API (click on ActiveRecord)
- CakePHP API
- AjaxScaffold
November 27th, 2006 at 6:13 pm
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...
November 28th, 2006 at 1:12 am
thanks for the tip, I'll look into it
December 6th, 2006 at 2:22 pm
There's better ActiveRecord implementation in the Akelos framework.
at www.akelos.org
check it out.
January 22nd, 2007 at 2:55 pm
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.
January 23rd, 2007 at 4:15 am
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
January 24th, 2007 at 11:39 pm
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?
January 29th, 2007 at 3:38 pm
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! :) )
February 2nd, 2007 at 3:11 pm
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
April 3rd, 2007 at 7:52 am
RoR rocks!
April 12th, 2007 at 3:42 pm
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.
April 16th, 2007 at 4:39 am
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!
April 23rd, 2007 at 9:35 pm
Thank you for this nice article,
I like both cakephp and Rails.
Did any one tried symphony ?
April 23rd, 2007 at 9:37 pm
If any any one has a comparison between cakephp and symphony it would be great
www.badrit.com
April 29th, 2007 at 4:57 pm
[...] 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! [...]
April 30th, 2007 at 12:52 pm
Thanks for the great work! It really is more than what was expected. I loved its simplicity! Keep up the good work!
May 2nd, 2007 at 11:07 pm
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...
May 4th, 2007 at 1:01 am
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..)
May 5th, 2007 at 10:44 am
[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... :)
September 17th, 2007 at 3:13 pm
[...] 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.” [...]
December 7th, 2007 at 1:24 am
Thanks for this great explaination this helped me make a choice between the frameworks.
regards,
Best
December 9th, 2007 at 12:57 pm
"then through it back to a function"
isn't it supposed to be "then throw it back to a function" ?
December 18th, 2007 at 9:22 am
Both frameworks works ok...
Feel free to use what you want...
January 4th, 2008 at 12:19 am
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 ;)
January 16th, 2008 at 10:38 am
http://www.youtube.com/watch?v=n1NVfDlU6yQ
http://www.youtube.com/watch?v=Ld919lziKgE
http://www.youtube.com/watch?v=GQXqWkWqnSw
February 3rd, 2008 at 9:15 am
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!
February 26th, 2008 at 8:26 am
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.......
March 21st, 2008 at 3:52 am
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
April 4th, 2008 at 12:59 am
[...] Rails vs. CakePHP Comparison [...]