# From CodeIgniter to Ruby on Rails: A Conversion

Today, we'll be creating a simple shoutbox using the CodeIgniter PHP framework. We'll then port this exact application, piece-by-piece, to Ruby on Rails!

Throughout this tutorial, we'll create a simple shoutbox application in CodeIgniter, and then port it over to Ruby on Rails. We'll be comparing the code between the two applications to see where they are similar, and where they differ. Learning Rails is much easier if you are already familiar with an MVC (Model, View, Controller) framework structure.

### Do I Need Previous CodeIgniter Experience?

Yes, or experience in PHP and another MVC framework (CakePHP, Zend etc.). Check out some of the other CI tutorials here on Nettuts, including the from scratch video series!

### Do I Need Previous Ruby/Rails Experience?

While it would help, no. I've done my best to make direct comparisons between Ruby and PHP, and between Rails and CodeIgniter, so by applying your existing knowledge it won't be too hard.

### Hello, CodeIgniter

Begin by downloading the CodeIgniter framework to your local/web server, and set up your database (I named it ci_shoutbox) with the following SQL commands:

As usual in CodeIgniter, enter your details into /system/application/config/database.php:

Then config.php:

And autoload.php:

Finally set the default controller inside routes.php:

#### Controller & Model

Since this is such a simple application, we only need one controller and one model. Inside /controllers/ create shouts.php:

And the model as /models/shout.php:

### Retrieving the Shouts

Our front page, the index, outputs the 10 latest shouts from the database. Start by adding the following to the Shouts controller:

On line 2, we call the all_shouts() function from the Shout model.
Following this, we load the relevant view file, and pass the $data variable along to it (CodeIgniter will automatically take apart the $data array, so that we can access the shouts simply as $shouts instead of $data['shouts']).

#### Calling the Database

Let's create the all_shouts() function in our model now:

This is relatively straight-forward. We retrieve the 10 most recent records from the 'shouts' table, and output them in descending order. This will build the following SQL command behind-the-scenes:

If any records were found, they are added to the $data array and returned to the controller. #### The View Inside the /views/ directory, create the following files and folders: • footer.php • header.php • /shouts/ • index.php Add the following to /shouts/index.php: On line 2 we include header.php. If any shouts were returned from the database, we loop through them using foreach and create a basic list with the author's Gravatar, their name and the message. If no shouts were found, we display an error message. Finally, we include the footer.php. Note that on line 7, we build the Gravatar URL. The URL contains an MD5 hash of the user's email address. We use PHP's strtolower() function to ensure the email is all lower-case in case the Gravatar service is case-sensitive. Continuing on, we need a form at the bottom of the page to add a new shout. Before we include the footer view file, add the following: On line 1 we use the form_open() function from CodeIgniter's Form helper. This generates a <form> opening tag with the relevant parameters, and will point to shouts/create (the Create function inside the Shouts controller). The rest is a normal HTML form, except we echo the set_value() function for each 'value'. We will be adding validation to the form shortly and this ensures that if there are any errors, the submitted data is automatically re-entered into the form. Finally, we'll need to create the header & footer. Add the following to /views/header.php: See on line 8, when including the stylesheet, we use the base_url() function from CodeIgniter's URL helper to generate the URL to the root of the site – this will put the stylesheet at http://example.com/css/style.css. Add the following to /views/footer.php: ### Submission & Validation Since the form directs to a Create function in the Shouts controller, let's create that now: On line 2 we retrieve the shouts (as we did on the index function), as they still need to be shown. Lines 4-6 are our validation rules. We first pass the input's 'name' from the submitted form to check, followed by a 'human-readable' version. The third parameter holds a pipe-separated ('|') list of validation rules. For example, we set all the fields as 'required' as well as run them through 'htmlspecialchars' before submission. 'Name' and 'Email' have a max length set, and the submitted email field must resemble an email address. If the validation fails, the index view is loaded again; otherwise we run the create() function from the Shout model. On line 13, we set a success message in the flash data which will be displayed on the next executed page. Before continuing, we must display the error and success messages (see images above) in our view. Add the following directly after we include the header in /views/shouts/index.php: #### Insert Into Database Inside the Shout model, enter the following: Very simple, we compile an array containing the submitted data, and insert it into the shouts table. #### Styling In the very root directory for your application – in the same directory as CodeIgniter's /system/ folder, create two new folders: /css/ and /images/. In the CSS folder, add the following to a file named style.css: And save the following images into the /images/ folder: (the images will be the correct size when saved!) back.png bg.png bot.png shout.png shoutbox.png top.png To confirm, your directory structure should look like the image below: And... done! If you think we wrote very little actual back-end code in CI, wait until we get to Rails where all database interaction is automated! ### Hello, Rails For this tutorial, I assume you already have Ruby, Rails and MySQL (or your preferred database engine) installed correctly on your system. If not, see the Rails installation guide and MySQL download page. If you happen to be running Mac OSX Leopard, Ruby and Rails both come pre-installed. It's also useful to know how to navigate in your operating system using the command line. For example to change directory, use cd foldername, or cd C:\Users\Dan etc. Rails provides a number of command-line tools to speed up development of your application. Inside the Terminal (or Command Prompt in Windows), navigate to the folder you wish to store your Rails projects in. Personally I store them in a /rails/ directory in my User area. #### The Set Up Run the following to dump a copy of Rails for your application: Here, Rails will install into a /shoutbox/ directory. As MySQL is my preferred database engine, I specify -d mysql. If you prefer to use MySQLlite (the default in Rails), you would simply run rails shoutbox. Navigate into the shoutbox directory: Now, we'll generate the Controller and Model: Rails has now generated our 'Shouts' controller and 'Shout' model. It's important to know that Rails encourages a strict naming style. Your controller should be named the plural of whatever it will deal with (eg. Shouts, Users, Listings). A controller typically will only deal with one model, which is named in the singular (eg. Shout, User, Listing). Following this standard will ensure Rails can use all it's functionality. Inside your shoutbox directory, open the /config/database.yml file, this stores our database details. Enter your details under the 'development' section: You can see Rails has automatically set the configuration file to be using the MySQL adapter. You will likely only need to alter the username and password. Don't worry, you should not have created the shoutbox_development database yet. We'll create that next. Next, open the /db/migrate/***_create_shouts.rb file (most versions of Rails will prefix the file name with the date and time): This is a database migration file. Rails use these to help developers keep their databases structured correctly since they can become messy when several developers are altering database tables at the same time. You will also be able to roll your database back to a previous version if you need to. In here, we will add our database fields: This may look scary, but it's very simple! t.string :name creates a 'name' field in the database, which will be stored as a string (ie. 'varchar'). The same goes for the 'email' field. A 'message' field is added and stored as text (as it is in SQL). You will notice Rails automatically included t.timestamps. This includes 'created_at' and 'updated_at' fields which Rails will automatically fill in when a field is created or updated. Also, Rails will automatically create an 'id' field, so we don't need to define that ourselves. This is equivalent to the following SQL command: While it can take a little getting-used-to when creating these migrations, they're much easier to type than SQL! Finally, run the following two commands in the Terminal to create and set up the database: The first command creates the database, named 'shoutbox_development'. The second runs any out-standing database migrations (in this case, our ***_create_shouts.rb file). Start the server with and then visit http://localhost:3000 (or whatever port the server says it is running on – in most cases it's 3000): To remove the default welcome page, first remove the file at /public/index.html, then inside /config/routes.rb, insert the following anywhere between the first and last lines: You will need to restart the server whenever you make alterations to the controller or to the routes – press Ctrl+C, then re-run ruby script/server. That concludes the configuration process for Rails. While this whole process may seem complicated right now, you can do it in just a few minutes, and once you get used to it, it's much quicker than setting up a CodeIgniter project. #### Dummy Data Before display the shouts, we'll need some data in the database to display. You could create these entries through your preferred database management program, however we're going to use a great Rails feature instead – the interactive console. From your application folder in the Terminal, run ruby script/console. This is an interactive Ruby interpreter, which is also hooked up to our Rails application, so we can interact with it! One very important thing to remember with regard to Rails, is that your model is automatically linked with the corresponding database table. For example, your 'Shout' model is linked with the 'shouts' table in your database – this is a key reason why following Rails' naming conventions can be very useful! Run the following ruby code inside the interactive console: Here, we invoke Rails' new method on the 'Shout' model – this will create a new record in the shouts database table. We also pass a hash containing the data we want to enter. This is stored in the 'shout' variable. Note: A 'hash' is what PHP calls an associate array – an array where you can also set your own key. A rough PHP equivalent of this code would be: Finally, save this into the database with: If you entered the code correctly, ruby should return 'true'. You can now retrieve this from the database with: The first command will find the most recent row in the shouts table and store it in the 'shout' variable. We can find look at a specific item with shout.name which should return whatever you entered as the 'name' for the record. Repeat the Shout.new and Shout.save process a few more times to add more records to the database. ### Displaying Shouts Inside the /app/controllers/shouts_controller.rb file, enter the following between the existing class statement: We call the all_shouts method from the 'Shout' model, and store the result inside the shouts instance variable (as seen by the @). In CodeIgniter, the equivalent code was: Some noticeable differences are: 1. Rails uses the '<' symbol in place of 'extends' when creating a class; 2. To create a function/method we use def instead of function; 3. Rails doesn't require a constructor method; 4. Rails automatically loads the view file for the current method. In this case, the view file is located at /app/views/shouts/index.html.erb; 5. It is already noticeable that code is much cleaner in Rails. You don't need parenthesis (brackets) when defining a funcion/method if it doesn't contain any parameters, we don't need to add a semi-colon at the end of each statement and there are no curly brackets in sight! #### The Model Inside /app/models/shout.rb enter the following inside the class to define the all_shouts function: Here, we run Rails' find on the Shout model (ie. the shouts table). We pass a hash telling the method to limit the number of results to 10 in descending order. This is the equivalent CodeIgniter code: Yeah… so much simpler! Also note that in Ruby, if you don't specifically return something, the last statement is automatically returned. For example, we could have used the following instead (although it would make no difference): #### The View In CodeIgniter, we had to manually include header & footer files in each view. Rails takes a slightly different approach. Inside /views/layouts/ create a file named application.html.erb with the following inside: This is predominantly a normal HTML layout, combining both our header and footer. On line 7 we include a link to a stylesheet. Rails provides a /public/ folder in which you include images, stylesheet, javascript files and any static HTML files. In this case, the code will output a link to a stylesheet at /public/stylesheets/style.css. Further down, on line 21 is <%= yield %>. This will insert the main view file for the specific page in this place. Why .html.erb? All view files in Rails first have the extension for the specific format you want to output as, followed by .erb so the server will interpret the Ruby code inside it. This means you could also have a .xml.erb file if you want to export in XML for certain pages, etc. <%= %> Ruby uses <% and %> to wrap any Ruby code to be interpreted, in the same way PHP uses <?php and ?>. On HTML pages, we use <%= ... %> (note the equals) to 'print' code. In PHP we use either <?php echo ... ?> or <?= ... ?> to 'echo' code. Inside /public/stylesheets/ create a file named style.css containing the same CSS we used in the CodeIgniter section. Also, paste the images from the CodeIgniter section into /public/images/. If you restart the server now, and reload your browser, you should see a 'Template is missing' error page. This is because we haven't yet created the actual view for the current page. The 'Template is missing' error page tells us what file it was expecting: "Missing template shouts/index.html.erb in view path app/views" So let's create that file now, and enter the following to test it out: Reload the page, and you should be greeted with the following (if not, check you have the stylesheet & images in the correct locations): #### Looping You will remember that in CodeIgniter, we used the code below to loop through and display each retrieved shout: The equivalent in Ruby is the following (replace the 'Hello, World!' message with this): On line 2 is a normal 'foreach'-style loop in Ruby. Instead of the foreach ($shouts as $shout) in PHP, we use for shout in @shouts in Ruby. The loop closes at end on line 16. On line 4 we build the Gravatar URL in almost the same way as in PHP, with a few exceptions: 1. In PHP, we use the dot character (.) to concatenate statements, Ruby uses the plus character (+), just like in JavaScript; 2. Ruby's version of PHP's md5() function is Digest::MD5.hexdigest(); 3. The h() function in Ruby is equivalent to PHP's htmlspecialchars(); 4. PHP uses -> to access an object (eg. $shout->email). Ruby uses a dot, (eg. shout.email);

5. To ensure the email address is in lower-case, we use strtolower(\$shout->email) in PHP. In Ruby, everything is an object and so we simply add .downcase to the end of a string or variable – shout.email.downcase. You could also .upcase, .reverse, etc.

Refresh the page in your browser, and you should now see the shoutbox messages!

#### Submission Form

Continuing on, we need to include the form at the bottom of the page for submitting new shouts. First, take a look at the following line:

This is a block from Rails' form helper to easily create forms. form_for :shout links the form directly with the Shout model.

:url = { :action = 'create ' } is a hash detailing where the form will direct to when submitted. In this case, the form will go to /shouts/create/ (Shouts controller, Create method). We could have typed: :url = { :controller = 'shouts', :action = 'create }, however the lack of a 'controller' key in the hash tells Rails to use the current controller.

Finally, do |f| stores everything before in an f variable. For example, we could create a textbox linked to this using f.text_field

Now we've explained that, enter this full form code at the bottom of your index view file:

And compare it with the CodeIgniter PHP version:

We make more use of Rails' form helper when creating the input fields, textarea and submit button. With f.text_field :name, :size = 20 we are creating a textbox named 'name' (matching the column in our database this should insert into). This would output in HTML as:

In the CodeIgniter version of the app, we set each input's 'value' field to <?= set_value('email') ?> so CodeIgniter will automatically re-populate the fields if they fail the validation tests.
In Rails, this is handled automatically since we are using Rails' form helper to create the inputs.

Refresh the page in your browser, and you should see the form at the bottom:

### Submission & Validation

The next step is to insert any submitted data into the database. The form directs to shouts/create, so let's create the create action now (inside the Controller):

On line 2, we retrieve all our current shouts from the database since they still need to be displayed.

At line 4 we load Rails' new function on our Shout model. You will remember we used Shout.new when inserting dummy data into the database via the interactive console.
We pass new our submitted data with params[] – this is how Rails accesses POST data.
This is loaded into the @shout instance variable.

When we used the interactive console, we used shout.save to save the data. If it was successful, it returns 'true', otherwise 'false' is returned. So on line 5 we check whether the shout can be saved into the database, if so, we load a success notice in the session's 'flashdata', and redirect back to the index.
Otherwise, we load index's view file through the render function.

#### Validation

You may be wondering where our validation is handled, since we did this in the controller in CodeIgniter. In Rails, we place the rules inside the Model.
When Rails attempts to insert data to the database (eg. with @shout.save), the Model will automatically check the data against our rules before attempting to save it. Thus, if validation fails, then @shout.save will return 'false', the view will be re-loaded and the error messages will display.

Inside the Shout model, insert the following before we define self.all_shouts:

In true Ruby style, the validation rules read pretty much like natural English. On line 1 we ensure a 'message' exists.

Next we check the length of the 'name' field – it must be between 1 and 255 characters in length. 1..255 defines a range. We could define a range of between 10 and 15 with 10..15, for example.

Finally, we check the submitted email is in the format of an email address using a regular expression. Basically, the submitted email must contain five parts:

1. A string containing a combination of letters, numbers, an underscore, full-stop or hyphen;
2. The @ symbol;
3. A string containing a combination of letters, numbers or a hyphen;
4. A dot;
5. A string containing a combination of letters or a hyphen.

#### And finally...

We now just need to display the error/success messages in the view (see above). Add the following at the top of the index view file:

On the first line we render any error messages for the shout form. We set :header_message and :message to nil (Ruby uses 'nil', PHP uses 'null') to stop the function displaying the normal messages it displays (we just want the error messages).

The second line displays our flash'ed success message. Note the if flash[:notice] at the end of the line. This ensures everything before it will attempt to display if the flash notice exists.
Obviously, we could also have done the following instead; however it would have had the same effect:

### That's It!

Go try it out, it should function exactly as the CodeIgniter version yet in quite a bit less code (which is also much easier to read!)

CodeIgniter:
Controller: 31 lines
Model: 33 lines
View: 69 lines
Total: 133 lines

Ruby on Rails:
Controller: 19 lines
Model: 11 lines
View: 64 lines
Total: 94 lines

While this tutorial may have made the process of developing a Rails application long-winded, take a look back through your code and see how simple it all is!

If this tutorial has sparked your interest in Ruby and Ruby on Rails, I strongly recommend picking up a copy of Rails for PHP Developers, Agile Web Development with Rails and/or Programming Ruby from the Pragmatic Programmers.

Now go! Go explore the world of Rails!