Ruby on Rails versus CakePHP: A Syntax Comparison Guide
My time is typically split between Interchange and Spree development, but in a recent project for JackThreads, I jumped back into CakePHP code. CakePHP is one of the more popular PHP MVC frameworks and is inspired by Rails. I decided to put together a quick syntax comparison guide between CakePHP and Rails since I occasionally have to look up how to do some Rails-y thing in CakePHP.
Basic | Ruby on Rails | CakePHP |
---|---|---|
MVC Code Inclusion | Rails is typically installed as a gem and source code lives in the user’s gem library. In theory, a modified version of the Rails source code can be “frozen” to your application, but I would guess this is pretty rare. | CakePHP is typically installed in the application directory in a “cake/” directory. The “app/” directory contains application specific code. From my experience, this organization has allowed me to easily debug CakePHP objects, but didn’t do much more for me. |
Application Directory Structure | app/ controllers/ models/ views/ helpers/ lib/ config/ public javascripts/ images/ stylesheets/ vendors/ plugins/ extensions/ | controllers/ models/ views/ layouts/ elements/ ... config/ webroot/ tmp/ plugins/ vendors/ |
Notes: | In Rails, layouts live in app/views/layouts/. In CakePHP, layouts live in views/layouts/ and helpers lie in views/helpers/. | |
Creating an Application | rails new my_app # Rails 3 after gem installation rails my_app # Rails <3 |
Download the compressed source code and create an application with the recommended directory structure. |
Models |
Ruby on Rails | CakePHP |
Validation | class Zone < ActiveRecord::Base validates_presence_of :name validates_uniqueness_of :name end |
class User extends AppModel { var $name = 'User'; var $validate = array( 'email' => array( 'email-create' => array( 'rule' => 'email', 'message' => 'Invalid e-mail.', 'required' => true, 'on' => 'create' ) ) ); } |
Relationships | class Order < ActiveRecord::Base belongs_to :user has_many :line_items end |
class Invite extends AppModel { var $name = 'Invite'; var $belongsTo = 'User'; var $hasMany = 'Campaigns'; } |
Special Relationships | class Address < ActiveRecord::Base has_many :billing_checkouts, :foreign_key => "bill_address_id", :class_name => "Checkout" end |
class Foo extends AppModel { var $name = 'Foo'; var $hasMany = array( 'SpecialEntity' => array( 'className' => 'SpecialEntity', 'foreignKey' => 'entity_id', 'conditions' => array('Special.entity_class' => 'Foo'), 'dependent' => true ), ); } |
Controllers |
Ruby on Rails | CakePHP |
Basic Syntax | class FoosController < ActionController::Base helper :taxons actions :show, :index |
class FooController extends AppController { var $name = 'Foo'; var $helpers = array('Server', 'Cart'); var $uses = array('SpecialEntity','User'); var $components = array('Thing1', 'Thing2'); var $layout = 'standard'; } |
Notes: | CakePHP and Rails use similar helper and layout declarations. In CakePHP, the $uses array initiates required models to be used in the controller, while in Rails all application models are available without an explicit include. In CakePHP, the $components array initiates required classes to be used in the controller, while in Rails you will use “include ClassName” to include a module. | |
Filters | class FoosController < ActionController::Base before_filter :load_data, :only => :show end |
class FooController extends AppController { var $name = 'Foo'; |
Setting View Variables | class FoosController < ActionController::Base def index @special_title = 'This is the Special Title!' end end |
class FooController extends AppController { var $name = 'Foo'; |
Views |
Ruby on Rails | CakePHP |
Variable Display | <%= @special_title %> |
= $special_title ?> |
Looping | <% @foos.each do |foo| -%> <%= foo.name %> <% end -%> |
= $item['name']; ?> |
Partial Views or Elements | <%= render :partial => 'shared/view_name', :locals => { :b => "abc" } %> |
element('account_menu', array('page_type' => 'contact')); ?> |
Notes: | In Rails, partial views typically can live anywhere in the app/views directory. A shared view will typically be seen in the app/views/shared/ directory and a model specific partial view will be seen in the app/views/model_name/ directory. In CakePHP, partial views are referred to as elements and live in the views/elements directory. | |
CSS and JS | <%= javascript_include_tag 'my_javascript', 'my_javascript2' %> <%= stylesheet_link_tag 'my_style' %> |
css(array('my_style.css'), null, array(), false); $javascript->link(array('my_javascript.js'), false); ?> |
Routing |
Ruby on Rails | CakePHP |
Basic | # Rails 3 match '/cart', :to => 'orders#edit', :via => :get, :as => :cart # Rails <3 map.login '/login', :controller => 'user_sessions', :action => 'new' |
Router::connect('/refer', array('controller' => 'invites', 'action' => 'refer')); Router::connect('/sales/:sale_id', array('controller' => 'sale', 'action' => 'show'), array('sale_id' => '[0-9]+')); |
Nested or Namespace Routing | # Rails 3 namespace :admin do resources :foos do collection do get :revenue get :profit end end end |
- |
Logging |
Ruby on Rails | CakePHP |
Where to? | tmp/log/production.log or tmp/log/debug.log | tmp/logs/debug.log or tmp/logs/error.log |
Logging Syntax | Rails.logger.warn "steph!" # Rails 3 logger.warn "steph!" # Rails <3or RAILS_DEFAULT_LOGGER.warn "steph!" |
$this->log('steph!', LOG_DEBUG); |
If you are looking for guidance on choosing one of these technologies, below are common arguments. In End Point’s case, we choose whatever technology makes the most sense for the client. We implemented a nifty solution for JackThreads to avoid a complete rewrite, described here in detail. We also work with existing open source ecommerce platforms such as Interchange and Spree and try to choose the best fit for each client.
Pick Me! | Ruby on Rails | CakePHP |
---|---|---|
|
|
Comments