<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	>

<channel>
	<title>Rida Al Barazi's Personal Blog &#187; Rails Project Story</title>
	<atom:link href="http://rida.me/blog/category/rails-project-story/feed/" rel="self" type="application/rss+xml" />
	<link>http://rida.me/blog</link>
	<description>Rida's Zone in Cyberspace</description>
	<pubDate>Sat, 14 Feb 2009 14:49:55 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Rails Project Story: 2. User Authentication</title>
		<link>http://rida.me/blog/2006/08/27/rails-project-story-2-user-authentication/</link>
		<comments>http://rida.me/blog/2006/08/27/rails-project-story-2-user-authentication/#comments</comments>
		<pubDate>Sun, 27 Aug 2006 16:21:55 +0000</pubDate>
		<dc:creator>Rida</dc:creator>
		
		<category><![CDATA[Development]]></category>

		<category><![CDATA[Programming]]></category>

		<category><![CDATA[Rails Project Story]]></category>

		<category><![CDATA[Ruby on Rails]]></category>

		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://www.ridaalbarazi.com/blog/2006/08/27/rails-project-story-2-user-authentication/</guid>
		<description><![CDATA[Here comes the second part of our story, last time in part one we met rails directory structure, designed a three tables database, created it in MySQL and linked it to our application then we let rails db schema create those tables for us and finally we generated a modest scaffold for our Books table.
If [...]]]></description>
			<content:encoded><![CDATA[<p>Here comes the second part of <a href="http://www.ridaalbarazi.com/blog/2006/08/16/rails-project-story/">our story</a>, last time in <a href="http://www.ridaalbarazi.com/blog/2006/08/20/rails-project-story-1-getting-started/">part one</a> we met rails directory structure, designed a three tables database, created it in MySQL and linked it to our application then we let rails db schema create those tables for us and finally we generated a modest scaffold for our <em>Books</em> table.</p>
<p>If you remember last week we added another table in our db schema file which was the <em>Users</em> table, today we will talk about users in our application and how to make our application a more social one.</p>
<p>The options we have in order to have a user management setup for our applications are mainly three:</p>
<ul>
<li>Do it ourselves from zero.</li>
<li>Use some decent plugin like <a href="http://technoweenie.stikipad.com/plugins/show/Acts+as+Authenticated"><strong>Acts As Authenticated</strong></a>.</li>
<li>Use a ready generator like <a href="http://wiki.rubyonrails.org/rails/pages/SaltedHashLoginGenerator"><strong>Salted Hash Login Generator</strong></a>.</li>
</ul>
<p>Before we choose between these three let&#8217;s see what are the main differences between them:</p>
<p>If we write our code from zero we will definitely learn more, we will have a better understanding of the whole process but at the same time we will be spending too much time on something became very regular and common in every web application and in some way we will be doing some not required extra work.</p>
<p><strong>Acts As Authenticated</strong> and <strong>Salted Hash Login Generator</strong> are almost the same from some functionality point of view but the main difference is that the act is more dynamic and customizable because it is simpler, it let us take care about few things that we should really be responsible of while the generator take care about everything in some more advance way, so personally I prefer to go for <strong>Acts As Authenticated</strong> for its simplicity and core functionality that will help us understand how things work and allowing us to add some extra functionalities by ourselves.</p>
<p>Acts in rails are some sort of plugins and extensions to our framework extending it with few extra features, there are many great acts we will use in this application, some of them are completely independent from rails and some like <strong>Acts As Taggable</strong> became so common to the level they got packaged with rails itself.</p>
<h3>Acts As Authenticated</h3>
<p>It&#8217;s a simple system that helps us deal with users in our applications, it generate the required code to support user authentication and management starting from the regular MVC code ending with migration and tests.</p>
<h4>Installation</h4>
<p>To start with we have first to install the plugin on our system, to do this we have first to update our repositories index and then install the plugin.</p>
<pre>
D:\\Projects\\Book Swap\\bookswap>ruby script/plugin source http://svn.techno-weenie.net/projects/plugins
Added 1 repositories.

D:\\Projects\\Book Swap\\bookswap>ruby script/plugin install acts_as_authenticated
+ ./acts_as_authenticated/CHANGELOG
+ ./acts_as_authenticated/README
.
.
.
Consult the Acts As Authenticated wiki for more: http://technoweenie.stikipad.com/plugins/show/Acts+as+Authenticated
</pre>
<h4>The Generator</h4>
<p>After installing the plugin now we are able to generate all the required files, acts_as_authenticated have mainly two generators, one for the authentication system itself, the core functionalities and their corresponding model, views and controller. And the other generator is the mailer, the one responsible for sending notification and verification emails to our registered users.</p>
<pre>
To use:

  ./script/generate authenticated user account

This generates a basic user model, a controller, some basic views, and tests.
</pre>
<p>So to generate the authentication system we have first to decide the controller name to be generated and remember here that the controller is the one that normally appear in our URL (to deal with the books controller we had to call <a href="http://localhost:3000/books">http://localhost:3000/books</a>) so what will be the best controller name for our users? Account? Readers? Owners? Well personally I prefer to stick with the defaults and the classics, at the end these are our applications <em>Users</em>, and this is what we called the database table earlier so let&#8217;s stick to it and name it <strong>&#8220;users&#8221;</strong>:</p>
<pre>
D:\\Projects\\Book Swap\\bookswap >ruby script/generate authenticated user users
      exists  app/models/
      exists  app/controllers/
      exists  app/helpers/
      create  app/views/users
      exists  test/functional/
      exists  test/unit/
      create  app/models/user.rb
      create  app/controllers/users_controller.rb
      create  lib/authenticated_system.rb
      create  lib/authenticated_test_helper.rb
      create  test/functional/users_controller_test.rb
      create  app/helpers/users_helper.rb
      create  test/unit/user_test.rb
      create  test/fixtures/users.yml
      create  app/views/users/index.rhtml
      create  app/views/users/login.rhtml
      create  app/views/users/signup.rhtml
      create  db/migrate
      create  db/migrate/001_create_users.rb
</pre>
<p>If we examine the generated files we can see that <em>acts_as_authenticated</em> has generated for us the user model, users controller and its corresponding views, a helper, some unit and fixture tests and finally a migration file, as we have all these files generated it seems that <strong>BookSwap</strong> is ready now to have users, let&#8217;s see if this is true <a href="http://localhost:3000/users">http://localhost:3000/users</a></p>
<p><img id="image100" src="http://www.ridaalbarazi.com/blog/wp-content/uploads/2006/08/users_signup.PNG" alt="users_signup.PNG" /></p>
<p>It seems that it works, it already directed us to the signup method <a href="http://localhost:3000/users/signup">http://localhost:3000/users/signup</a>, ok let&#8217;s give it a try and see what will happen (click to enlarge):</p>
<p><a href="http://www.ridaalbarazi.com/blog/wp-content/uploads/2006/08/users_signup_error.PNG" rel="lightbox" title="User Signup Error"><img src="http://www.ridaalbarazi.com/blog/wp-content/uploads/2006/08/users_signup_error.PNG" width="450" height="330" alt="User Signup Error" /></a></p>
<p>Oops, we have a problem, but at least we have some information that we can work with to understand what we have done wrong.</p>
<h4>Fixing The Conflict</h4>
<p>With the user friendly error page we should be able to catch what we&#8217;ve done wrong, it&#8217;s saying: <em><strong>&#8220;undefined local variable or method `crypted_password&#8217; for #&lt;User:0&#215;39499b8&gt;&#8221;</strong></em>, so basically the problem is in <em>&#8220;crypted_password&#8221;</em> and it is in the model <em>User</em>, we remember that the Model is the one that deals with the database, if you remember from our first part in the db schema definition we named the password column <em>&#8220;salted_password&#8221;</em>:</p>
<p>Error: Could not open schema.rb</p>
<p>So from where did this <em>&#8220;crypted_password&#8221;</em> come from?</p>
<h4>Back to Migrations</h4>
<p>Maybe it&#8217;s time to go back and check what&#8217;s inside the migration file that <em>acts_as_authenticated</em> generated for us and and check if it has anything realted:</p>
<p>Error: Could not open 001_create_users.rb</p>
<p>First let&#8217;s understand the migration process more, the migration is made to allow us move up and down in our application with a decent control over our database modification, in this case we can understand that <em>acts_as_authenticated</em> did create the migration file for us so we migrate to it.</p>
<p>Any migration file is separated into two parts, <strong>up</strong> and <strong>down</strong>. From the names <strong>&#8220;up&#8221;</strong> is the actions which will take place when we move forward in our migration like migrating from 4 to 5 for example, and <strong>&#8220;down&#8221;</strong> will hold the actions that will be executed when we move backward in our migrations like migrating from 6 to 5 for example.</p>
<p>The <em>001_create_users.rb</em> migration file creates a table in its <strong>up</strong> method and drop it in its <strong>down</strong> method, the table it creates is the <em>Users</em> table which we already created earlier in our schema, it almost have all the columns, few more and some with different names, here we can find the mysterious <strong>&#8220;crypted_password&#8221;</strong> we saw in the error page, it&#8217;s the column we named as <strong>&#8220;salted_password&#8221;</strong>, so we found what&#8217;s wrong, now how to fix this conflict?</p>
<p>We have to write our own migration instead of using the default migration generated by <em>acts_as_authenticated</em>, we will tweak it to suit our needs. First we don&#8217;t need to create the <em>Users</em> table as it is already created, we don&#8217;t need to recreate the fields we have already created as well but we need the new fields required by <em>acts_as_authenticated</em> and sure we have to fix and <em>rename</em> the field <strong>salted_password</strong> into <strong>crypted_password</strong>. This will make <strong>&#8220;up&#8221;</strong> method like this:</p>
<p>Error: Could not open 001_create_users_up.rb</p>
<p>Instead of the <em><a href="http://api.rubyonrails.com/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#M000604">create_table</a></em> method we used some individual methods that deals with an existing table, <em><a href="http://api.rubyonrails.com/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#M000607">add_column</a></em>, <em><a href="http://api.rubyonrails.com/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#M000608">remove_column</a></em> and <em><a href="http://api.rubyonrails.com/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#M000611">rename_column</a></em> are simple methods that takes the table name as their first parameter and the column name as their second, only the <em>rename_column</em> method takes an extra parameter which is the new column name.</p>
<p>As this is the first migration file we have it got the 001 numbers at the beginning of its name automatically, from now on any new migration will get a serial prefix to its name that indicate its place among other migrations.</p>
<p>Whenever we do any changes or modifications to our database we have to support going back by defining the opposite actions in the <strong>&#8220;down&#8221;</strong> method of our migration as follows:</p>
<p>Error: Could not open 001_create_users_down.rb</p>
<p>So at the end our modified <em>001_create_users.rb</em> file will end up like this:</p>
<p>Error: Could not open 001_create_users_new.rb</p>
<p>Logically we have solved the conflict error but there is still one step left which is migrating our application to the latest migration available and for now it is 001, to migrate our application we have to call the command &#8220;rake migrate&#8221;, if we called it without any parameter it will automatically migrate our database to the latest migration available, if we specified the <strong>&#8220;VERSION=<em>X</em>&#8220;</strong> parameter it will migrate the application to migration <strong><em>X</em></strong> whether it is newer or older from our current migration level.</p>
<pre>
D:\\Projects\\Book Swap\\bookswap>rake migrate
(in G:/Projects/Book Swap/bookswap)
== CreateUsers: migrating =====================================================
-- rename_column(:users, :salted_password, :crypted_password)
   -> 0.3590s
-- add_column(:users, :salt, :string, {:limit=>40})
   -> 0.3280s
-- add_column(:users, :created_at, :datetime)
   -> 0.3600s
-- add_column(:users, :updated_at, :datetime)
   -> 0.3430s
-- add_column(:users, :remember_token, :string)
   -> 0.3440s
-- add_column(:users, :remember_token_expires_at, :datetime)
   -> 0.3600s
== CreateUsers: migrated (2.0940s) ============================================</pre>
<p>Back to our application checking if the user system is working now, let&#8217;s try to sign up again and see what we will get (<a href="http://localhost:3000/users/signup">http://localhost:3000/users/signup</a>):</p>
<p><img id="image98" src="http://www.ridaalbarazi.com/blog/wp-content/uploads/2006/08/users_after_successful_login.PNG" alt="users_after_successful_login.PNG" /></p>
<p><em>&#8220;Train delayed? and what&#8217;s to say?&#8221;</em> nice poetry after such a cool process, so we are signed up and logged in now, this is what <em>acts_as_authenticated</em> can give us so far and the rest is on us. </p>
<p>Have you noticed that the column <em>fullname</em> didn&#8217;t show up in the signup page? That&#8217;s because the templates generated by <em>acts_as_authenticated</em> plugin don&#8217;t know about it <em>YET</em>.</p>
<h3>Tailoring</h3>
<p>To be able to tailor and customize the authenticated system we have to understand the generated files and know how to deal with them and we will start with the views:</p>
<p>The generated templates are three, <em>login</em>, <em>signup</em> and <em>index</em>, they are all placed under the &#8220;<em>users</em>&#8221; subdirectory in our <em>app/views</em> directory, what we want is to allow users to add their fullnames when they signup so let&#8217;s have a quick look at the <em>signup.rhtml</em> template:</p>
<p>Error: Could not open signup_old.rhtml</p>
<p>It looks that we have a pattern for every property of the user object to generate its corresponding form input, if we followed the same pattern to generate the required input for the user fullname our template will look like this:</p>
<p>Error: Could not open signup.rhtml</p>
<p>This template like any other <strong>rhtml</strong> view template contains two types of code, the basic <em>xhtml/html</em> code and an embedded ruby code which we call <strong>ERb</strong>. To embed a ruby code in our views we have to surround it with <strong><em>&lt;%</em></strong> and <strong><em>%&gt;</em></strong> this will execute the ruby code but it will not show any output so it&#8217;s called <strong>&#8220;evaluation ERb block&#8221;</strong>, if we want to show the output of this code we have to add an equal sign after the introductory signs so it will be surrounded by <strong><em>&lt;%=</em></strong> and <strong><em>%&gt;</em></strong> and this is called <strong>&#8220;output ERb block&#8221;</strong>.</p>
<p>In any of the <strong>ERb</strong> block types we will deal mainly with two things, first is the <em>ActionController</em> methods and actions, these will help us generate the required <em>xhtml/html</em>, <em>js</em> and <em>xml</em> code in a dynamic smooth way.</p>
<p>The second thing we will deal with in our views is <em>the instance variable</em> received from the related action in the related controller, each view will be parsed after its corresponding action in its related controller is requested, in that particular action we set some instance variables that we can manipulate in our views, we will see that in more details soon.</p>
<h3>How is it working?</h3>
<p>In order to understand the code and the way it is generated in <em>signup.rhtml</em> let&#8217;s have a look at the parsed version of it, the html source code of the page we get in our browser when we call <a href="http://localhost:3000/users/signup">http://localhost:3000/users/signup</a>:</p>
<p>Error: Could not open signup.html</p>
<p>Back to our <em>rhtml</em> template we notice that it starts with an output ERb block with the method <em><a href="http://api.rubyonrails.com/classes/ActionView/Helpers/ActiveRecordHelper.html#M000460">error_messages_for</a></em> which will output all the error messages of the user object in this form if there is any, as we don&#8217;t have any errors here we didn&#8217;t find any related html code in the parsed version.</p>
<p>Then comes an evaluation ERb block that opens a block by its turn, the <a href="http://api.rubyonrails.com/classes/ActionView/Helpers/FormHelper.html#M000387">form_for</a> method do the required preparation to output a form fully customized to hold the information of a specific object and by ready I mean setting this form inputs names and ids to form a set of the object&#8217;s data in the post parameters. So what we do is to specify the object name we are preparing this form for, which in our case <em>&#8220;user&#8221;</em>, we can also specify the action this form will be directed to when it&#8217;s submitted, if we don&#8217;t specify any (like in our case) it will be submitted to itself so our form will be submitted back to the <em>signup</em> action of the <em>users</em> controller.</p>
<p>The <em>form_for</em> method prepared a form helper object for the &#8220;user&#8221; object and name it &#8220;f&#8221;, then the generating of the required inputs for each column started by simply calling their corresponding helper methods, notice that only two methods are used so far: <em>text_field</em> and <em>password_field</em> and they are called as methods of the form helper object called &#8220;f&#8221;, notice as well that these methods are called in an output ERb block so they can return their output in the parsed template.</p>
<p>Let me try to simplify this code by trying to write it in plain English: <em>&#8220;Start a form for a new user then generate the required text fields and password fields for this user and then post them back to the same current page.&#8221;</em></p>
<p>The main idea of setting the names and ids of the generated inputs is to simplify the way we deal with them in our actions as post parameters, rails has a standard for this and therefore it has the ready tools to generate what&#8217;s required to follow these standards and get things faster.</p>
<p>After we are done with our form fields we find a <em>submit_tag</em> named <em>&#8220;Sign up&#8221;</em> then the <em>form_for</em> block is  simply closed by an <em>&#8220;end&#8221;</em> and we are done. When someone signup and fill all these fields and hit the sign up button the form data will be posted to the same action <strong>&#8220;signup&#8221;</strong> where it will be handled to add a new user to the <em>Users</em> table accordingly, if it faced any errors it will return to the same form and show the errors at the top (as the results of the <em>error_messages_for</em> method), if not it will simply login to our poetry page.</p>
<h3>Are We Logged In?</h3>
<p>Now let&#8217;s change this literal poetry in the <em>index.rhtml</em> template to some code poetry, how about we change the output of this view depending on the status of the user, if he/she is logged in we show a link to <em>logout</em>, if not we show links to either <em>signup</em> or to <em>login</em>. I don&#8217;t think this is difficult it&#8217;s just a quick <em>if</em> statement:</p>
<p>Error: Could not open index_new.rhtml</p>
<p>I guess the code is self-explanatory now, I just want to note that we used the method <em><strong>logged_in?</strong></em>, in ruby whenever there is a method with a question mark <em><strong>&#8220;?&#8221;</strong></em> at the end of it will return a Boolean, True or False, so in English it&#8217;s like a simple question, <em>is the current user logged in?</em> this method is a part of the <em>acts_as_authenticated</em> plugin.</p>
<p>The other thing I wanted to talk about here is the <a href="http://api.rubyonrails.com/classes/ActionView/Helpers/UrlHelper.html#M000378"><em>link_to</em></a> method, it is an ActionView helper method, it generates an anchor, takes the first parameter as the anchor name and the second as the action name we want to link to, it will automatically understand and generate the corresponding URL of the action we specify, for example when we specify the &#8220;logout&#8221; action it will know automatically that its URL is <a href="http://localhost:3000/users/logout">http://localhost:3000/users/logout</a>.</p>
<p>So we have changed our <em>index.rhtml</em> file, now let&#8217;s see if it&#8217;s working and how it will look like, remember that our last state where logged in after we signed up and saw the lovely poetry:</p>
<p><img id="logged_in" src="http://www.ridaalbarazi.com/blog/wp-content/uploads/2006/08/users_index_logged_in.PNG" alt="Logged in users index page" /></p>
<p>We are logged in, that&#8217;s true, it seems that everything is really working fine and we don&#8217;t have any problems so far, how about the link to <em>&#8220;logout&#8221;</em>? is it working? let&#8217;s check out:</p>
<p><img id="logged_out" src="http://www.ridaalbarazi.com/blog/wp-content/uploads/2006/08/users_index_logged_out.PNG" alt="Logged out users index page" /></p>
<p>Yes it is working, we are logged out now and we have one of two options, either to login again or to signup for a new account, try logging in and out again to see how it&#8217;s working and then let&#8217;s try a new signup to see if the fullname field we have added is present or not:</p>
<p><img id="signed_up" src="http://www.ridaalbarazi.com/blog/wp-content/uploads/2006/08/users_signup_new.PNG" alt="New users signup page" /></p>
<p>Wonderful, we have a simple user authentication system now that we modified a little, so far it works for signup, login and logout, it doesn&#8217;t do anything more yet but at least it helped us understand few concepts and how things work at the backend.</p>
<h3>More Security by Filtering</h3>
<p>To care more about security and to get the most benefit out of the latest rails 1.1.6 security release let&#8217;s use the new method of ActionController (released in rails 1.1.6) <em><a href="http://api.rubyonrails.org/classes/ActionController/Base.html#M000201">&#8220;filter_parameter_logging&#8221;</a></em>:</p>
<p><em><strong>&#8220;<a href="http://api.rubyonrails.org/classes/ActionController/Base.html#M000201">ActionController#filter_parameter_logging</a> lets you filter form data that you don&#8217;t want saved in the log. This is useful for preventing sensitive data like passwords and credit card numbers from being logged in the clear, for keeping huge pieces of data from clogging the log file, and so on.&#8221;</strong> from <a href="http://weblog.rubyonrails.org/2006/8/21/filtered-parameter-logging">Filtered Parameter Logging</a> of <a href="http://weblog.rubyonrails.org/2006/8/21/filtered-parameter-logging">the Ruby on Rails official Blog</a>.</em></p>
<p>This method job –as clarified in rails weblog- is to filter fields from being logged, in our case what we want to filter is the <em>password fields</em> and we will do that by adding the <em><strong>filter_parameter_logging</strong></em> line to our application controller in <em>controllers/application.rb</em>:</p>
<p>Error: Could not open application_filtered.rb</p>
<p>By doing this the <strong>password</strong> and <strong>password_confirmation</strong> fields will never be logged anymore and will be replaced by &#8220;<strong>[FILTERED]</strong>&#8221; in the log files, to check that yourself you can check your <em>log/development.log</em> file and see how the passwords of the users added to the system earlier were plainly logged while the passwords of any new users will be replaced with &#8220;[FILTERED]&#8220;.</p>
<h3>Summary</h3>
<p>In this part we have implemented the Acts As Authenticated plugin into our application, modified it a little and understood few backend behaviors specifically the way the view templates handle ERb code, we also had a better look at Migrations and understood how they help us have a better control over our database modifications in a very dynamic way.</p>
<p>During the next week I will release a sidenote post on how to checkout the project files from the subversion repository I&#8217;m using for it, I&#8217;m also working on creating packaged files for each part of the tutorial and will release it on RubyForge soon too.</p>
<p>In the next part we will talk about relationships, as for now we have a user system and a simple books system, we will link them together using some magic relationship mapping from ActiveRecord maybe we will do some testing as well to ensure things are working properly, so&#8230; see you next week.</p>
]]></content:encoded>
			<wfw:commentRss>http://rida.me/blog/2006/08/27/rails-project-story-2-user-authentication/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Rails Project Story: 1. Getting Started</title>
		<link>http://rida.me/blog/2006/08/20/rails-project-story-1-getting-started/</link>
		<comments>http://rida.me/blog/2006/08/20/rails-project-story-1-getting-started/#comments</comments>
		<pubDate>Sun, 20 Aug 2006 15:24:21 +0000</pubDate>
		<dc:creator>Rida</dc:creator>
		
		<category><![CDATA[Development]]></category>

		<category><![CDATA[Programming]]></category>

		<category><![CDATA[Rails Project Story]]></category>

		<category><![CDATA[Ruby on Rails]]></category>

		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://www.ridaalbarazi.com/blog/2006/08/20/rails-project-story-1-getting-started/</guid>
		<description><![CDATA[So here is the first part of the previously announced Rails Project Story, in this part we are going to understand the Rails directory structure, design a very basic database to start with, link it to our rails application, setup the rails database schema for it and finally try the famous scaffolding feature that everybody [...]]]></description>
			<content:encoded><![CDATA[<p>So here is the first part of the previously announced <a href="http://www.ridaalbarazi.com/blog/2006/08/16/rails-project-story/">Rails Project Story</a>, in this part we are going to understand the Rails directory structure, design a very basic database to start with, link it to our rails application, setup the rails database schema for it and finally try the famous scaffolding feature that everybody talks about.</p>
<p>It seems that I underestimated the amount of work this tutorial is going to take that&#8217;s why I&#8217;m a day late, because of that I will change the weekday each part of this series will come up from Saturday to Sunday and sorry about this delay.</p>
<p>If you remember our project is <strong>BookSwap</strong>, <em>a small system based on users, it will give them the chance to exchange and swap books between each others from their online bookshelves that they create</em>. so let&#8217;s get started:</p>
<p>Normally I prefer to get something up and running as soon as I can, at least to enjoy seeing results from the very beginning of my project work and this is what we are going to do with this project as well, so to start let&#8217;s decide what is the simplest database design we can start with?</p>
<h3>Database Schema</h3>
<p>Basically from the light definition of our project we can tell that this project includes two main things: <em>users</em> and <em>books</em>, and from here we will go, we need two tables, one to hold the users data and we will call it Users and another one for books data and we will call it Books and now let&#8217;s discuss the relationship between these two tables</p>
<p>Obviously every user will have many books, and many users can own the same book (I mean the same title not the same physical book), so the relationship we have here is the <em>many-to-many</em> relationship which requires a third table in our database called <em>users_books</em>, therefore our database should look like this (db model is generated using <a href="http://www.fabforce.net/dbdesigner4/">DBDesigner4</a>):</p>
<p><img id="image91" src="http://www.ridaalbarazi.com/blog/wp-content/uploads/2006/08/users_books1.png" alt="Users and Books tables" /></p>
<p>As you can tell from the database model above, I have mentioned the common and very basic columns of each table; fullname, login, email and salted_password for the Users table and title, author, publisher and ISBN for the Books table and naturally both of them have the default ID column as well.</p>
<p>We will use MySQL as the database server for this application, it&#8217;s time to create the three databases we will work with on our way:</p>
<p><em><strong>bookswap_production</strong></em>: This will be the database we will use when we finish our development work and ready to have a live and completely working web application, that&#8217;s why it&#8217;s called the production database, it should contain the most stable version of our database structure with the most stable version of our code that&#8217;s why we separated it from the development database.</p>
<p><em><strong>bookswap_development</strong>t</em>: As you can tell, this is the database that we will play with during our development process, whenever we need to change anything or touch anything related to the database this is the one we should be dealing with in order to keep our production database in peace.</p>
<p><em><strong>bookswap_test</strong></em>: In a sooner part of this tutorial we will cover the testing of our application, we will write code that will test our code and this testing code will deal with a completely separate database from both development and production databases, it will deal with the test database as it will require a lot of data insertions and deletion while testing which we want to keep away from other live and development databases.</p>
<p>If you have a <acronym title="Graphical User Interface">GUI</acronym> for your MySQL server you can create the above databases from there or we can simply use the command line admin tool:</p>
<pre>
D:\\Projects>mysqladmin -–user root -–password create bookswap_production
Enter password: ********

D:\\Projects>mysqladmin -–user root –-password create bookswap_development
Enter password: ********

D:\\Projects>mysqladmin -–user root -–password create bookswap_test
Enter password: ********
</pre>
<p>We will only create the databases now, we will not create any tables or relationships yet and actually we will do all that in Ruby and Rails after we get to know the directory structure of our rails application.</p>
<h3>Generating The Rails Application</h3>
<p><em>Before we get started with generating the rails application let&#8217;s just clarify few things, we are using Rails 1.1.6 for this application which got <a href="http://weblog.rubyonrails.org/2006/8/10/rails-1-1-6-backports-and-full-disclosure">announced</a> only few days ago (from the date of this post), so if you have Rails installed earlier before the update please upgrade before we proceed.</em></p>
<p>To generate our rails application we have to run the <strong>rails</strong> command, personally I have created a directory called &#8220;Book Swap&#8221; where I will store everything related to this project, including the rails app itself. So all I have to do now is to run the <strong>&#8220;rails&#8221;</strong> command in my directory with the project name to get my files generated.</p>
<pre>
D:\\Project\\Book Swap>rails bookswap
      exists
      create  app/controllers
      create  app/helpers
      create  app/models
      .
      .
      .
      create  doc/README_FOR_APP
      create  log/server.log
      create  log/production.log
      create  log/development.log
      create  log/test.log
</pre>
<p>I guess you agree with me that these are a lot of files and directories that Rails has generated for us, maybe we should give them a quick scan and try to understand what they are for and what we will be dealing with more frequently:</p>
<h3>File Structure</h3>
<p><img id="image93" class="rfloated" src="http://www.ridaalbarazi.com/blog/wp-content/uploads/2006/08/file_structure.png" alt="File Structure" /></p>
<h4>app</h4>
<p>This directory is the one that will contain most of our working files, it already contains four subdirectories (controllers, helpers, models and views), that is made to support the <acronym title="Module View Controller">MVC</acronym> nature of Rails, in brief the MVC methodology is based on separating our code into three levels: </p>
<p>First we have <strong>the Model</strong> which carries the core functions and responsible for all the data handling and manipulation, then comes <strong>the Controller</strong> which normally interacts with the model to retrieve data and prepare it to be viewed by <strong>the View</strong> which by its turn is the responsible of doing all the &#8220;show&#8221; business.</p>
<p>As for <strong>Helpers</strong>, they are the view supporters, when we reach the level that we have too much code in the view we better go and make a helper function and use it instead, once we start writing code we will get a better understanding of all these concepts which will happen very soon.</p>
<p><strong>Behind The Scenes</strong></p>
<p>All of these models, controllers and views are just the children of a bigger and more general parts of Rails, actually Rails is a union of different parts for each task which makes it more understandable and customizable to fit our best needs.</p>
<p><a href="http://api.rubyonrails.com/classes/ActiveRecord/Base.html">ActiveRecord</a> is the part of Rails that&#8217;s responsible of interacting with the database and lets us deal with it as a complete object oriented solution, which really sounds like the model behavior (core functions and data manipulation) which is true, normally the model classes in our <em>models</em> directory are subclasses of ActiveRecord where they inherit the magic powers of it and get such strong tools to deal with the database.</p>
<p><em><strong>&#8220;Active Record objects don’t specify their attributes directly, but rather infer them from the table definition with which they’re linked. Adding, removing, and changing attributes and their type is done directly in the database. Any change is instantly reflected in the Active Record objects. The mapping that binds a given Active Record class to a certain database table will happen automatically in most common cases, but can be overwritten for the uncommon ones.&#8221;</strong> From <a href=" http://api.rubyonrails.com/classes/ActiveRecord/Base.html">Rails API</a></em></p>
<p>Following the same path Rails also depends on <a href="http://api.rubyonrails.com/classes/ActionController/Base.html">ActionController</a> for its controllers, which is the midpoint between the views and the models, it receives the web requests from one side, activate the corresponding action which will contact the model for few  data objects and then render the views to show the results.</p>
<p><em><strong>&#8220;Action Controllers are the core of a web request in Rails. They are made up of one or more actions that are executed on request and then either render a template or redirect to another action. An action is defined as a public method on the controller, which will automatically be made accessible to the web-server through Rails Routes.&#8221;</strong> From <a href=" http://api.rubyonrails.com/classes/ActionController/Base.html">Rails API</a></em></p>
<p>And finally we&#8217;ve got the views which are <a href="http://api.rubyonrails.com/classes/ActionView/Base.html">ActionView</a> templates, we will see how they are just normal html, js or xml pages but with embedded Ruby code inside which also known as <acronym title="Embedded Ruby">ERb</acronym>, this embedded code helps us represent the data with some behavior and have a better separation between our design and our backend code.</p>
<p><em><strong>&#8220;Action View templates can be written in three ways. If the template file has a +.rhtml+ extension then it uses a mixture of ERb (included in Ruby) and HTML. If the template file has a +.rxml+ extension then Jim Weirich’s Builder::XmlMarkup library is used. If the template file has a +.rjs+ extension then it will use ActionView::Helpers::PrototypeHelper::JavaScriptGenerator.&#8221;</strong> From <a href=" http://api.rubyonrails.com/classes/ActionView/Base.html">Rails API</a></em></p>
<h4>config</h4>
<p>From its name, config directory is where the configurations files are stored, the database link file, routs and environments files. <em>database.yml</em> is the database link file, where we will setup our database connection settings, <em>environment.rb</em> is the file where we specify our application environment, remember when we talked about development, production and test databases; each one of those is related to one separate environment as well that we can run our application on.</p>
<p>Config directory include environments subdirectory too which include environments configurations files, for each environment a  different file, to control all the environments we have the father file we&#8217;ve just talked about environment.rb.</p>
<p>Finally comes the <em>routes.rb</em> file which (as it&#8217;s named) take care of all the web requests routing in our application, starting from some very basics routes up to a very complicated ones, it is very helpful for making clean and meaningful URLs as well.</p>
<h4>components</h4>
<p>In this directory we can create and store components which are something like a small application with model, controller and view that we can use all over our website instead of repeating ourselves for some modules.</p>
<h4>db</h4>
<p>From its name, the <em>db</em> directory will store our database related files, earlier we used to store the SQL files that generate our database structure but now it will hold only ruby files. It will store the schema and migrations files that we will discuss after a while in this part.</p>
<p>When we first generate our rails application the db folder will be empty but as we move along it will contain the schema.rb file that stores our database schema definitions and a subdirectory named &#8220;<em>migrations</em>&#8221; to store the versioned migrations we will create.</p>
<h4>lib</h4>
<p>Sometimes but not always there are some code that we want to write and it doesn&#8217;t fit under any of the MVC hierarchy, such custom code will be stored in the <em>lib</em> directory.</p>
<h4>public</h4>
<p>An interesting fact about Rails that none of these directories we are talking about is viewable or accessable online except for &#8220;<em>public</em>&#8220;, it contains the cgi/fcgi dispatchers that will do all the underground work to deal with the routes and our application, it also contains the <em>images</em>, <em>stylesheets</em> and <em>javascripts</em> subdirectories that we will be calling in our <em>views</em> and <em>layouts</em>.</p>
<h4>script</h4>
<p>You will notice when go a little further that rails is full of generators and embedded scripts that help us along the road to generate and create many things and even run a tiny web server as well the <em>script</em> directory is where all these stuff are hidden.</p>
<h4>test</h4>
<p>The <em>test</em> directory is where all the automotive tests are stored, there are functional tests for our controllers with some fixtures to load and a couple of unit tests for our models as well.</p>
<h4>vendor</h4>
<p>As in any application, sometimes we don&#8217;t want to reinvent the wheel, we don&#8217;t want to do something that&#8217;s already done, rails as an open source framework have many wonderful plugins and resources available that we can use in our applications and we will do that as well in BookSwap, all these external libraries and plugins will be stored in the <em>vendor</em> directory.</p>
<h4>doc, log, and tmp</h4>
<p>These three directories we don&#8217;t interact with their files much as they are automatically generated and updated, the <em>log</em> directory will store the log files of our web server for each environment, <em>tmp</em> will store the session, cache and socket temporary generated files and finally <em>doc</em> will store the html documentation that we will generate for our application (we will cover this up in some later part).</p>
<h3>Link The Database</h3>
<p>After we had this quick overview over the file structure in Rails we have to configure our rails application to connect to the databases we have created earlier, the responsible configuration for this is <em>config/database.yml</em> which normally looks like (notice that the databases names are exactly like the one we&#8217;ve created as they follow the project name):</p>
<p>Error: Could not open original_database.yml</p>
<p>Now for the sake of <acronym title="Don’t Repeat Yourself">DRY</acronym> &#8216;ing our configuration file we will change it a little bit and add our database connection details as well to:</p>
<p>Error: Could not open dried_database.yml</p>
<p>Basically what we have done is taking all the repeated information from the three database configurations parts, collect them under one reference and call this reference back in the configurations parts, by doing this we are not only DRY &#8216;ing our database configuration file but we also allowed different database engines to be defined more easily.</p>
<p>So our Rails application is linked to its blank databases using the MySQL adapter and it&#8217;s time to implement the structure we&#8217;ve decided on earlier using the rails schema and migrations facilities.</p>
<h3>Rails + Database = Schema + Migrations</h3>
<p>Migration in rails is the way Rails allow us to move back and forth in our application easily without losing any data from our databases but also keeping track of all the database structure changes from version to version (something like version control for our code files).</p>
<p>Database schema in Rails is very first database schema our rails application will have so if we want to install it on a new machine or load our database structure in any different database server it will be ready as a schema file that gets accumulated by the migrations files to move between versions.</p>
<p>In this part we will deal only with the schema part and later on with our versions and modifications we will get to know migrations better and have a closer look at them, now let&#8217;s generate the schema file and see how it looks like:</p>
<pre>
D:\\Projects\\Book Swap\\bookswap>rake db_schema_dump
</pre>
<p>This command will create a new file in our <em>db</em> folder named <em>schema.rb</em>, this file will hold all the starting schema setup and definitions and as this is a fresh application it will be empty from any definitions yet:</p>
<p>Error: Could not open original_schema.rb</p>
<p>Now let&#8217;s implement the basic database schema we agreed on at the beginning of this part, three tables with few fields, after the modification our <em>schema.rb</em> will be like this:</p>
<p>Error: Could not open schema.rb</p>
<p>If you read the above code you can easily understand that we simply created three database tables and identified their columns accordingly but notice also that we didn&#8217;t define the id column of the <em>users</em> and <em>books</em> tables, this is because ActiveRecord will create it by default.<br />
<em><br />
<a href="http://api.rubyonrails.com/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#M000604">create_table</a></em> is a simple method that generates SQL code of creating a table, we used its block form to add columns of our desired type, in the block form an instance of the table definition is created as <strong><em>&#8220;t&#8221;</em></strong> and when we call <em>t.column</em> it&#8217;s like if we say <em>add_column</em> in the regular form of the <em>create_table</em> method.</p>
<p>We have a schema file that contains our database structure, we have a rails application linked correctly to our database all we have to do now is to tell rails to import this schema to the linked database:</p>
<pre>
D:\\Projects\\Book Swap\\bookswap>rake db_schema_import
(in D:/Projects/Book Swap/bookswap)
-- create_table("users")
   -> 0.3440s
-- create_table("books")
   -> 0.1410s
-- create_table("users_books")
   -> 0.1720s
</pre>
<p>Running this command will import the database schema defined in <em>schema.rb</em> to our development database and that&#8217;s because the default environment of any new rails project is the development environment which can be changed and configured at anytime in <em>config/environment.rb</em>.</p>
<p>With this ruby-based database schema file we have saved ourselves from being attached to any database engine, Rails supports too many database engines like SQLite, Oracle, DB2, SQL Server and PostgreSQL, now our application can work with any of those by simply changing the connection adapter in <em>config/database.yml</em> file and import our schema to it using the above rake command.</p>
<p>This is one of the reasons why many designers or non-developers liked Ruby on Rails when they started to learn it as their first web development language and framework, Ruby has this beautiful self-explanatory code and Rails is full with Agile practices, it saved us from dealing with any SQL code and made our application cross-database-engines with Schema and Migrations.</p>
<p>All this read and all this steps and we didn&#8217;t see anything in action yet, maybe it&#8217;s time for us to try <a href="http://wiki.rubyonrails.org/rails/pages/ScaffoldGenerator">Scaffolding</a> which is a quick auto-generator that we tell it about a table we want to scaffold and it will generate all the required Model, Controller and Views to connect with it and control it.</p>
<p>By running the following command we will be able to add, edit, delete and list all the data of our Books table:</p>
<pre>
D:\\Projects\\Book Swap\\bookswap>ruby script/generate scaffold Book Books
      exists  app/controllers/
      exists  app/helpers/
      create  app/views/books
      exists  test/functional/
  dependency  model
      exists    app/models/
      exists    test/unit/
      exists    test/fixtures/
      create    app/models/book.rb
      create    test/unit/book_test.rb
      create    test/fixtures/books.yml
      create  app/views/books/_form.rhtml
      create  app/views/books/list.rhtml
      create  app/views/books/show.rhtml
      create  app/views/books/new.rhtml
      create  app/views/books/edit.rhtml
      create  app/controllers/books_controller.rb
      create  test/functional/books_controller_test.rb
      create  app/helpers/books_helper.rb
      create  app/views/layouts/books.rhtml
      create  public/stylesheets/scaffold.css
</pre>
<p>This command will ask Ruby to run the scaffold generator to create the MVC setup for our table Books, the first parameter after <em>&#8220;scaffold&#8221;</em> is the Model/Table name and notice here that the table name here is not plural as we have specified it in our schema.rb, it&#8217;s Book not Books and this is because Rails will take care of this with it&#8217;s pluralization magic.</p>
<p>The second parameter in the scaffold command is the Controller/View name, basically it will create controller of the same name and a directory in the views directory named books with few templates for each action in the created controller.</p>
<p>Few other files got created too in the process, a helper and few test files, for now we will not deal with any of them  but we can at least understand that for each data table of our database we can have all these structured files, a model to interact with the database and present the table data as objects, a controller which interact with these objects, filter them and prepare them to be viewed by the views which are templates with light embedded ruby code.</p>
<p>With this very minimum work, few commands and modifying a couple of files, we didn&#8217;t even write any code yet but we have something up and running and it&#8217;s time to have a sneak view on how it will look like.</p>
<pre>
D:\\Projects\\Book Swap\\bookswap>ruby script/server
=> Booting WEBrick...
=> Rails application started on http://0.0.0.0:3000
=> Ctrl-C to shutdown server; call with --help for options
[2006-08-20 16:49:04] INFO  WEBrick 1.3.1
[2006-08-20 16:49:04] INFO  ruby 1.8.4 (2005-12-24) [i386-mswin32]
[2006-08-20 16:49:04] INFO  WEBrick::HTTPServer#start: pid=5652 port=3000
</pre>
<p>We don&#8217;t even need to install a webserver while developing a rails application, we can simply try it with <a href="http://www.webrick.org/">WEBrick</a>, the simple http server bundled with rails. It will run by default on port 3000 on the localhost server so let&#8217;s check it out <a href=" http://localhost:3000">http://localhost:3000</a>.</p>
<p><img id="image63" src="http://www.ridaalbarazi.com/blog/wp-content/uploads/2006/06/testapp.png" alt="TestApp Rails Welcome Screen" /></p>
<p>Rails welcomes us, read this page as it has some useful information that we have discussed some and will discuss the rest (routes specifically) in depth later in other parts.</p>
<p>So where is the magic? We have generated a scaffold for the books table and we chose the controller/view name to be books, rails understand that and it will run everything automatically under the following mapping: <em><strong>servername:port/controller/action</strong></em>, in our case the servername is <em>localhost</em> running on port <em>3000</em>, the controller we&#8217;ve created is named <em>books</em> but we don&#8217;t know any action yet but let&#8217;s try this: <a href="http://localhost:3000/books/">http://localhost:3000/books/</a> </p>
<p><img id="image94" src="http://www.ridaalbarazi.com/blog/wp-content/uploads/2006/08/scaffold_books_list.PNG" alt="Book Listing" /></p>
<p>Great!! We have a page with the title <strong>&#8220;Listing Books&#8221;</strong>, an empty table with same headers of our columns names and finally a link that says <em>&#8220;New book&#8221;</em>. By clicking on this link we will see something more wonderful, a ready form, lovely and simple that allows us to add new books to our database.</p>
<p><img id="image95" src="http://www.ridaalbarazi.com/blog/wp-content/uploads/2006/08/scaffold_books_new.PNG" alt="New Book" /></p>
<p>Let&#8217;s try filling it out with some data and add the book, where will we go next? Back to the listing page but now it&#8217;s not empty like before, we have the new book we&#8217;ve just created listed there:</p>
<p><img id="image96" src="http://www.ridaalbarazi.com/blog/wp-content/uploads/2006/08/scaffold_books_add.PNG" alt="Added Book" /></p>
<p>What else have we got there? Three links in same row with our recently created book, <em>Show</em>, <em>Edit</em> and <em>Destroy</em>.. Do we have to explain? Clicking on <em>Show</em> will take us to a separate page that shows only the data of this particular row, <em>Edit</em> will take us to a form page loaded with the information of this record, ready to be edited while <em>Destroy</em> will popup a warning message before it will delete this record. This is it, one line only and the scaffold generator created all this for us.</p>
<p>Follow the URLs of each action and see how they are very meaningful and clean, all this web requests are handled in config/routes.rb as we said above, with the default route (mapping) as /:controller/:action/:id so for example if we go to http://localhost:3000/ books/show/2   routes.rb will forward this request to the books controller to run the show action on the book with 2 as its id.</p>
<p>Naturally scaffolding is not made to be used on its own, it&#8217;s made just to provide us with the very basics functions in a very simple way so we can understand how things work but we have to do the rest and modify the code to what perfectly suit our needs and that is what we will discuss in the next parts.</p>
<h3>At The End</h3>
<p>In this part we have met Rails in a little depth, had a quick look at the file structure it generates and understood some of the migrations and schema magic as well, technically we have now a basic rails application for books where we can add, edit and delete any record at any time after we wrote a very minimum amount of code and left the rest on Rails to take care of.</p>
<p>In the next part we will talk about creating some more tables, discussing migrations a little further and getting a better look with a nice interface and see how to implement the design with our Rails application as well, sorry for the length of this part and see you next week…</p>
]]></content:encoded>
			<wfw:commentRss>http://rida.me/blog/2006/08/20/rails-project-story-1-getting-started/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>

