In this post, the following Concepts are explained
- Web Applications and Rails
- What Rails can Do
- Where Rails Came From
- Rails Philosophies
- More Rails Philosophies
- MVC
- Model
- View Part 1
- View Part 2
- Controller
Web Applications and Rails
Summary:
Basic introduction to Web applications in general. The architecture of Web browser(Cleint) and Server(which also includes a Database) is explained. Model-View-Controller architecture of Rails is also explained very well. A must see for newbies.
What Rails can Do
Summary:
Examples of usages of Ruby on Rails in some of the Deployed and running web applications. The author also explains a web app he had developed with Rails (Please dont be upset with the layout of this app, the functionality matters ). The app developed by him shows the power of Rails prototyping at a much faster rate compared to other frameworks. He also goes on to explain different Rails website showcased on Rubyonrails official website.
Where Rails Came From
Summary:
This explains the background for the development for Ruby on Rails. A company based out of Chicago by name 37Signals hired a smart developer from Denmark by name David Heinemeier Hansson to work on a Collaborating Web-app Basecamp . Because of the Geographical distance between them, an interesting Design pattern and philosophy was developed which has crept its way into Ruby on Rails. Rails has been extracted into a framework from a product (BaseCamp), which is not quite the usual case. The author also recommends to watch the Video presentation by David on Rails and its background.
Rails Philosophies
Summary:
This covers the Philosophies behind Rails
One piece of information should be present only at a single place. Most of the code should be placed only once in specific places based on MVC paradigm. This makes the code highly efficient and easy to maintain.
Rails follows certain Conventions, that is it has defaults for most aspects of putting together a web application. If you follow these conventions, you can develop Web apps rapidly not bothering about a lot of Configurations which you would otherwise do in Java or normal PHP. This also makes your code base very minimal
More Rails Philosophies
Summary:
Another philosophy behind Rails is Agile Development. It emphasizes more on important things rather than conventional standards. In the following list, the items in bold text have emphasis over the normal text.
- Individuals and interactions over processes and tools
- Working software over comprehensive documentation
- Customer collaboration over contract negotiation
- Responding to change over following a plan
MVC
Summary:
A brief history and introduction to MVC architecture. The pattern was first described in 1979 by Trygve Reenskaug, then working on Smalltalk at Xerox PARC
The components of MVC are Model-View and Controller.
- Model maintains the state of your application.
- View is responsible for generating User Interface through which a website user interacts with it
- Controller can be perceived as the part which controls and co-ordinates the View and Model.
In Rails, M-V-C files are under separate folders and Model and Controller files have .rb extension whereas View files have a .rhtml(html with Ruby Code embedded) or .rjs (JavaScript embedded with Ruby Code).In Rails, the MVC works as follows.
A URL from Web-browser interacts with a Controller (not a View directly). Controller then interacts with Model which makes queries into the Database. The Database replies with the output to Model which will return to Controller in the form of Object Oriented array, which can be manipulated and then sent to the View which renders the html and Javascript on the Web-browser.
Model
Summary:
Model interacts with database and maintains state of the database in a Rails Application. In Rails, we extensively use Active Record which is a ORM (Object-Relational Mapping ) mechanism. Every model-class in Rails app corresponds to a Table in our Database. Every attribute in a model-class is mapped to a column in the corresponding database table. All these are done automatically once you instantiate a Model (Thanks to Rails, which takes care of this headache ). Author also shows and explains some Code of a model class. The ActiveRecord is intelligent enough to update itself with any Database changes you make. So it truly uses DRY i.e you dont have to make any changes in the Model file after you make changes in the Database. He also explains the syntax of a Model file(tech.rb), which is
[sourcecode language=’ruby’]
class Tech < ActiveRecord::Base #Tech as a subclass of ActiveRecord Class
has_many: work_requests # one to many mapping, work_requests is another model-class
has_many: assigned_teches
has_many: work_requests_notes
def self.login(name,password)
find(:first, :condtions => [“name = ? and password = ?”, name, password])
end
def try_to_login
Tech.login(self.name, self.password)
end
end
[/sourcecode]
View Part 1
Summary:
View is the Part of the MVC architecture which renders or parses the generated html and javascript code to the Browser. Compared to Model and Controller files(.rb) which are Classes and have only Ruby code in them, View files(.rhtml or .rjs) have html and/or javascript code and have Ruby code embedded in them between <% …some ruby code…%>
The author shows and explains a simple Recipe list which has Recipes with add/edit/delete and search functionalities. He goes through the Controller code which will in-turn parse to View to render html to browser. Name of the Controller file and Controller class are related and is generated by Rails. In this example, the controller’s class name is RecipeController and the controller file name is recipe_controller.rb , which is as follows
[sourcecode language=’ruby’]
class RecipeController < ApplicationController # Subclass of ApplicationController
def list #function or method. An important convention is that it parses a view file by the same name. i.e list.rhtml and is not explicitly mentioned
@all_recipes = Recipe.find(:all) #It finds all the recipes and stores in instance variable 'all_recipes'
end
def view
@a_recipe = Recipe.find(params[:id]) #it finds a recipe with a given id
@all_recipes = Recipe.find(:all) #It finds all the recipes
end
def show_add_recipe
end
def search
title = "%" + @params[:title] + "%"
@all_recipes = Recipe.find(:all, :condtions=>[“title like ?”, title])
end
def add_recipe
@a_recipe = Recipe.new(params[:new_recipe])
@a_recipe.save
redirect_to :action => ‘list’
end
def delete_the_recipe
Recipe.find(params[:id]).destroy
redirect_to :action => ‘list’
end
def edit_recipe
@recipe_to_edit = Recipe.find(params[:id])
end
def save_recipe
@recipe_to_update = Recipe.find(@params[:a_recipe_id])
@recipe_to_update.update_attributes(@params[:recipe_to_edit])
redirect_to :action => ‘list’
end
end
[/sourcecode]
View Part 2
Summary:
From the previous Video, we look at list.rhtml. It is called by ‘list’ method/function in RecipeController class. The beauty of Rails is that you dont have to specify the name of the View file, its convention is to have the Controller class name itself. In this case it is list.rhtml whose content is as follows
[sourcecode language=’html’]
<%= flash[:notice] %>
<%= render(:partial => ‘the_list”)%>
[/sourcecode]
In the above snippet of code, the major part is normal html. The Ruby code is put between <% …some code … %> if its not printing anything on the browser . If you are outputting or printing something, we use <%= ..some code.. %>.
The line <%= render(:partial => “the_list”) %> renders another view, in this case its a partial view. The partial views can only be called from main views and hence can be used repeatedly at many places. The partial view file is named _the_list.rhtml . There is an underscore before the file name to distinguish it as a partial view. The contents of ‘_the_list.rhtml’ file is as follows
[sourcecode language=’html’]
<%=link_to "View Recipe", :action=> ‘view’, :id=> a_recipe %> | <%=a_recipe.title %> | <%=a_recipe.description %> | <%=link_to "Edit", :action=> ‘edit_recipe’, :id=> a_recipe %> | <%=link_to "Delete", :action=> ‘delete_the_recipe’, :id=> a_recipe %> |
<%= render(:partial => “search_form”)%>
<%= link_to "Add New Recipe", :action => ‘show_add_recipe’ %>
[/sourcecode]
In the above snippet of code,
- @all_recipes which is parsed from RecipeController is taken on a Loop.
- On every iteration, variable ‘a_recipe’ is rendered in a new table-row.
- To print the title of a recipe, we use a_recipe.title and similarly for description, we use a_recipe.description.
- In <%= link_to ‘View Recipe”, action=> ‘view’, :id=> a_recipe %> , link_to is a Ruby function which builds an anchor or link with text “View Recipe” and clicking on it will trigger ‘view’ function in RecipeController and parses ‘id’ as an argument.
- <%= render(:partial => “search_form”) %> will render “_the_search_form.rhtml” file
Controller
Summary:
Controller can be thought of a co-ordinator between a model and a view. A controller is usually called by a URL from the web-browser. Say there is a URL request of http://0.0.0.0:3000/recipe/list , it directly goes to controller recipe, whose filename is recipe_controller.rb and whose class name is RecipeController. All these would seem a bit confusing at first, but once you are familiar with the conventions, it would be a cake walk in future. The next part of the url after the controller name is ‘list’, which is the function name inside ‘recipe’ controller.
Lets explore ‘recipe_controller.rb’ file
[sourcecode language=’ruby’]
class RecipeController < ApplicationController # Subclass of ApplicationController, Class is i
def list #function or method. An important convention is that it parses a view file by the same name. i.e list.rhtml and is not explicitly mentioned
@all_recipes = Recipe.find(:all) #It finds all the recipes and stores in instance variable 'all_recipes'
end
def view
@a_recipe = Recipe.find(params[:id]) #it finds a recipe with a given id
@all_recipes = Recipe.find(:all) #It finds all the recipes
end
def show_add_recipe
end
def search
title = "%" + @params[:title] + "%"
@all_recipes = Recipe.find(:all, :condtions=>[“title like ?”, title])
end
def add_recipe
@a_recipe = Recipe.new(params[:new_recipe])
@a_recipe.save
redirect_to :action => ‘list’
end
def delete_the_recipe
Recipe.find(params[:id]).destroy
redirect_to :action => ‘list’
end
def edit_recipe
@recipe_to_edit = Recipe.find(params[:id])
end
def save_recipe
@recipe_to_update = Recipe.find(@params[:a_recipe_id])
@recipe_to_update.update_attributes(@params[:recipe_to_edit])
redirect_to :action => ‘list’
end
end
[/sourcecode]
In the following snippet of code, RecipeController class is made a sub-class of ApplicationController, meaning it derives all the properties of ApplicationController (Inheritance property of OOP). The class should always be terminated by ‘end’
[sourcecode language=’ruby’]
class RecipeController < ApplicationController
.....
.....
end
[/sourcecode]
In the following snippet of code, 'list' is a function/method. It is defined by keyword 'def' followed by its name. It is terminated by 'end'. Whatever is in between them is executed upon calling the function. In this case, there is a ActiveRecord Model named 'Recipe'. Recipe.find(:all) will interact with recipe corresponding table in database and get all the rows. The relational data from database is converted into Object by ActiveRecord and it is assigned to instance variable @all_recipes in the form of an array. Once this is done, the function will then call the view file with the same name as its, and parse the instance variables. In this case, it would be 'list.rhtml' as we had covered in the previous video summary.
[sourcecode language='ruby']
def list
@all_recipes = Recipe.find(:all)
end
[/sourcecode]
Since a Controller is the co-ordinator for Views and Models, if we have less code in View and more in Controller, it would become easy to maintain and update the code.
Disclaimer: The Screencasts are not recorded by me. I have just embedded them from Youtube. The original Videos area a part of Virtual Training Company, who give Online Training and the author for Ruby on Rails Series is Mr. Al Anderson. If you are benefited from these, you may register there by paying certain amount or order a CD from them.