Ruby On Rails Gautam Rege Josh Software Pvt. Ltd.
Speaker Introduction 9 years Software Experience BE – PICT Working in rails since 2006 Co-founded Josh Software – 2007 Previous Experience Cybage, Zensar, Symantec
Part – 1 Ruby on Rails Introduction
History of Ruby Father of Ruby – Yukihiro Matsumoto, a.k.a. “Matz”, Japan, 1995 Ruby is an Object Oriented Scripting Language Object Oriented helps in designing applications Scripting makes it faster and quicker to develop and redeploy.
Ruby Vs Python Python was the first OO script but its not a pure OO. There is no real encapsulation. Indentation !! def foo: print “This is the first line” print “This is second line” print “This is a syntax error” Serious Ruby Competitor Lots of python plugins and auto-install features Very popular today Caveats: Python – Why the name?
Ruby Vs Perl Perl is really a procedural language. OO Perl was introduced later. Syntax difficult to understand: $ \ @ % Excellent stream parser.. That was the original purpose. Caveats: Perl - Practical Extraction and Report Language
Ruby Vs Perl contd.. foreach $item(@fields) {   if ($db{$item}) {   print "conflict on $item\n";   $err ++;   next;   }  $db{$item} = \@fields;  } fields.each { |item| puts “conflict on #{item}” if fields.include?(item) }
Features of Ruby Pure Object Oriented Script No indentation issues. Readable code. Blocks and Iterators Instance and Class variables Caveats: What is the difference between, Proc, Lamda, a normal function
What do I choose anyway?? Perl is for people who believe that ‘old is gold’ and are set in their ways. Python is for ‘veterans’: people more comfortable on unix and vi than on Windows and Word! Ruby is for ‘enthusiasts’. You treat Ruby like you ‘pet’. You code because you enjoy it, watch it grow AND groom it as you like.
Overall Comparison Rails Pylons cgi/perl Web-frameworks    Plug-ins / auto-installation    Object Oriented Nature  Weak References (leaks)    Garbage Collection    Loose Data Typing    Data Types: Arrays, Hash Ruby Python Perl Features
Web Technologies Java – J2EE Python – Pylons, CGI PHP Perl – CGI Ruby – Rails .NET – ASP, C#
J2EE, .NET Web Development J2EE. .NET are very evolved and very good for robust and heavy applications. They support different levels of tier architecture – EJB, databases Excellent Security – application and code Excellent Load Balancing and clustering support Deployment is complicated Development is slow Very expensive for commercial deployment
CGI / Perl & PHP Simple architecture – so very fast WordPress is a PHP (XML-RPC) site Facebook Very difficult to support multi-tier architecture Security is weak Poor clustering support SQL centric code Typically procedural in nature Not suited for complicated web applications Very good for simple websites with small dynamic content
Pylons Pylons is the Python Web-framework Follows MVC pattern Relatively very new. Based on Rails architecture
Ruby on Rails Pure MVC framework Model View Controller Evolved over the past 4 years Authentication / Authorization very strong Being slowly adopted for heavy web applications
Ruby On Rails contd.. Support simple multi-tier architecture Webserver Database Application Server Good clustering support with Nginx + thin, Apache + passenger Security at code level is weak i.e. no source code encryption support yet.
Rails in the Real World Who uses Rails today? Twitter, Facebook Applications Vastly used as automated QA in large companies One of the pioneers of Agile Methodology JRuby – Java Ruby interpreter
Part 2 – Rails Architecture
Terminologies MVC Model - View – Controller Design Pattern REST Representational State Transfer ORM Object Relational Mapping Scaffold Building code skeletons. Migrations Managing the database tables and columns
Model – View – Controller
Model - Overview Maintains state of an object / application. Manages the actual data involved. Validates object information In Rails: It is directly mapped to the database table via ORM It is independent of Database nuances. Models supports relationships Models have bulk of rails code ActiveRecord
Controller – Overview Control the logical flow of the request. Interact with model and render the views In Rails: Controllers manage authorization, sessions. Controllers decide how the request is processed. Render view according to business logic. ActionController
View – Overview Views are HTML renderers Render dynamic pages based on templates. XML Json HTML JS (Ajax) In Rails Should contain very less or NO logic Erb (Embedded Ruby ) is supported. ActionView
MVC in Rails
Routing in Rails http://host:port/:controller/:action/:id They determine Which controller Which action Which object Custom routes can also be setup.
A word about RESTfull Rails Routes: map.resources :teams
Session Break Coffee ?
Part 2.1 ActiveRecord Database Connectors Mysql, pgsql, sqlite ORM Validations Relationships
Object Relational Mapping Database create table `customers` ( `id` int(11) auto_increment, `name` varchar(64), `age`int, primary key `id`) Model class Customer < ActiveRecord::Base end Object access cust = Customer.create puts “#{cust.name}, #{cust.age}”
Database “rules” Rules would mean guidelines. They help in writing lesser code and allow easier access from Rails code All table names should be plural: customers, products, categories, people All tables should have `id` as primary key which is an auto_increment All tables should have ‘_id` suffix as foreign keys. Example: `customer_id` in `products` table
Database “rules” contd.. All datetime fields should have `_at` suffix. Example: `created_at` Avoid composite keys use model validations instead They are new supported in Rails 2.1.2 onwards Model name should be singular. Model Customer maps to `customers` table Model Category maps to `categories` table (!!) Model Person maps to `people` table (!!)
Part 2.4 Migrations Migrations are routines which help us manage the database. Versions are maintained in the database itself in a table called schema_migrations This controls relationships at model level and not database level. rake db:migrate
Example of Migration class CreateAddresses < ActiveRecord::Migration def self.up create_table :addresses do |t| t.string :street t.integer :zip, :default => 0 t.references :customer t.timestamps end end def self.down drop_table :addresses end end This creates customer_id field in database. Relation between Customer and Address is determined by the models. i.e. class Customer has_one :address
Rake Ruby build program similar to ‘make’ Rakefiles (rake‘s version of Makefiles) are completely defined in standard Ruby syntax. No XML files to edit. No quirky Makefile syntax to worry about (tab or space issues!) rake –T in rails environment show default tasks User can add new tasks in lib/tasks/filename.rake It loads the rails environment – development, production or test or custom.
Part 3 – Hands-on work Building a Rails Application
Ruby on Rails Installation Install ruby on Windows / Linux. Latest stable version: Ruby 1.8.6 , 1.8.7 Latest version: Ruby 1.9 http://rubyonrails.org/download Install rubygems Link: http:// rubyforge.org/frs/?group_id =126 Latest stable version: 1.3.3 gem install rails Latest stable version: 2.3.2 Recommended: 2.1.2 Install MySQL 5.x Link: http://dev.mysql.com/downloads/mysql/5.1.html#downloads
Setup the Environment Ensure installation is good and versions are correct. ruby –v >= 1.8.6 gem –v >= 1.3.2 rails –v >= 2.1.0 mysql –version >= 5.0.x Editor: Scite Create the rails project cmd> rails <name> -d mysql
Rails Project Layout ..../app ......../controller ......../helpers ......../models ......../views ............/layouts ..../config ..../components ..../db ..../doc ..../lib ..../log ..../public ..../script ..../test ..../tmp ..../vendor ......../plugins Core Application code: Controllers, Helpers, Models, Views Configuration for database, initializers,routes Database migrations Additional or custom libraries, rake tasks etc. The HTDOC for this web project. This contains JS, CSS, images etc. External plugins for this project.
Session Break Coffee ?
ActiveRecord Validations validate Generic validation method that can be used for custom validation validates_uniqueness_of :name validates_numericality_of :age validates_presence_of :address validates_format_of :email, :with => <regex>
ActiveRecord Callbacks before_create after_create before_save after_save before_update after_update before_destroy after_destroy before_validation after_validation
ActiveRecord Relations has_many 1 ↔ m relationship with child belongs_to 1 ↔ 1 relationship with parent has_one 1 ↔ 1 relationship with child has_many :through => Earlier versions: has_and_belongs_to_many m ↔ m relationship with peer
Database revisit create table `customers` ( `id` int(11) auto_increment, `name` varchar(64), `age`int, primary key `id`) create table `addresses` ( `id` int(11) auto_increment, `street` varchar(64), `zip_code` varchar(64), `customer_id` int, foreign key customer_id references customer(id) primary key `id`) This line is actually not necessary in Rails as migrations handle this.
has_one ↔ belongs_to class Customer < ActiveRecord::Base has_one :address end class Address < ActiveRecord::Base belongs_to :customer end cust = Customer.new(:name => ‘Gautam Rege’) address = Address.new(:customer => cust, :street => ‘SB Road’, :zip => ‘411016’) cust.address => #<Address object> address.customer => # <Customer object> Cust.address.zip => Zip code of address for this customer
Database revisit create table `bank_accounts` ( `id` int(11) auto_increment, `acc_number` varchar(64), `branch` varchar(64), `customer_id` int, foreign key customer_id references customer(id) primary key `id`)
has_many ↔ belongs_to class Customer < ActiveRecord::Base has_many :bank_accounts end class BankAccount < ActiveRecord::Base belongs_to :customer end cust = Customer.new(:name => ‘Gautam Rege’) bank = BankAccount.new(:customer => cust, :acc_number => ‘123456’, :branch => ‘XYZ’) cust.bank_accounts =>[ #<BankAccount object> array ] bank.customer => # <Customer object> Camelization !!
Database Revist create table `products` ( `id` int(11) auto_increment, `cost` varchar(64), primary key `id`) create table `categories` ( `id` int(11) auto_increment, `name` varchar(64), primary key `id`) create table `product_categories` ( `id` int(11) auto_increment, `product_id` int, `category_id` int primary key `id`)
has_many :through => class Customer < ActiveRecord::Base has_many :bank_account_customers has_many :bank_accounts :through => :bank_account_customers end class BankAccount < ActiveRecord::Base has_many : bank_account_customers has_many :customers :through => : bank_account_customers end class BankAccountCustomer < ActiveRecord::Base belongs_to :bank_account belongs_to :customer end customer.bank_accounts => [ #<BankAccount object> array ] acc.customers => [ #<Customer object> array ]
Named Scopes ActiveRecord::NamedScope::Scope A scope represents a narrowing of a database query Returns a collection but its not an Array. It resembles the association object constructed by a has_many declaration Unlike arrays, They are “composable” - named_scopes can be chained!
Named Scope example class Customer < ActiveRecord::Base has_many :bank_accounts named_scope :hni, :conditions => [ ‘hni = ?’ true ] named_scope :high_risk lambda do | list | { :joins => ‘risk_customer_lists’, :conditions => [‘name in (?)’, list ] } End @customers = Customer.hni @customers = Customer.hni @customers = @customers.high_risk(terrorists) @customers = Customer.hni.high_risk(terrorists)
Hands On! Creating & updating migrations Adding relationships Rails console Rails dbconsole
Session Break Coffee ?
Part 2.2 ActionController Rails HTTP request processing Helpers Filters Accessing the models Rendering the views
Processing a HTTP Rails request http:// host:port /:controller/:action/:id http://some.url:3000/customer/show/1 “ _controller” suffix in app/controllers customers_controller.rb All actions are mapped as functions in the controller. “def show” params[:id] = 1 All views default to app/views/<controller>/<action>.erb.html app/views/customers/show.html.erb
Helpers Helpers are not classes but modules. They mainly assist views with some helper functions and global etc. Helper methods are accessible in controllers and views. Hmm.. Why are helpers not available to the model?
Filters before_filter, after_filter are controller class methods Filters can be used to check authentication, caching, or auditing before the intended action is performed. Filters have access to the request, response headers class CustomerController < ApplicationController before_filter :login_required, :except => [:list, :show] def login_required # check if user is logged in end end
ActionController example app/controllers/customer_controller.rb: class CustomerController < ApplicationController def index # default function when no action is called. :redirect_to :action => ‘list’ end def list @customers = Customer.find(:all) end def show @customer = Customer.find(params[:id]) end end GET and POST parameters are accessed via params
Part 2.3 ActionView Embedded Ruby (erb) Rails Magic Instance variables (@variables) are copied into and ActionView instance before view invocation That is why all instance variables created in ActionController are available ‘as is’ to the views.
Partials Partials are views which can be rendered in other views. They are always stored with a ‘_’ prefix _form.erb.html :render :partial => ‘form’
Layouts The basic page layout for all pages. Default layout: application.erb.html Layout can be changed by specifying ‘layout <name>’ in the controller.
Rendering Views Embedded Ruby code without rendering <% %> Rendering dynamic data <%= %> Example: <% @customers.each do |cust| %> Name: <%= cust.name %> <% end %>
FormHelpers <% form_for :customer @customer :url => {:action => :create} do |f| %> <%= f.text_field :name %> <%= f.date_select :birth_date %> <%= submit_tag 'Create' %> <% end %>
Ajax on Rails Link_to_remote Remote_form_for Rails supports different rendering formats Html Xml Js json
Session Break Coffee ?
Building a Rails Application Installing Ruby, rubygems and Rails Rails Project Layout Design the application Write Migrations Generate Scaffold Deploy & Run Rails helps you build web applications really fast but YOU STILL HAVE TO DESIGN IT !!
Application Idea?? Lets think of one now Pre-decided
Survey Application A survey is a set of questions which a user answers Application should have multiple surveys and a user should be able to choose any survey. User should be able to see all the questions in the survey. User should be able to answer one or more questions. User can choose to leave some questions un-answered. All answers are free-text
Survey Application Result of the survey for a user should be shown. User can edit his previous answer to some question in a survey Anyone can see the results of the survey for any user. There is no need of any authentication.
Is the above too easy ??  Questions can be free-text or multiple choice. User authorization User should be able to change only his/her answers later Statistical survey data How many users took which survey? Most popular survey User with maximum surveys
Survey Application survey questions answers users
Relationships A survey has_many questions A question has_many answers A user has_many answers A user has_many surveys A survey has_many users
Migrations Survey Migration t.string :name User Migration T.string :name User_surveys T.references :user T.references :survey
Migrations contd.. Questions Migration T.string value T.references :survey Answer migration T.string :value T.references :question T.references :user
Scaffolding Generate scaffolds ./script/generate scaffold Customer This generates the model, controller, helper and migration for customer app/models/customer.rb app/controllers/customers_controller.rb App/helpers/customer_helper.rb App/views/customers/*.erb.html Db/migrate/<version>_create_customers.rb
Checklist Migrations completed? Model relationships added? Config/database.yml correct? Database created? rake db:create rake db:migrate Server started?
Actual Development (finally) Add code to controller Add validation to models Modify the views Adding some CSS and JS
Session Break Coffee ?
Deploying the application Starting rails server RAILS_ROOT/script/start Stopping the application ^C URL: http://localhost:3000 Production Deployment ./script/server -eproduction
Configuring routes Resource Maps map.resources :customer => Customer route http://host:port/customers/new http://host:port/customers/show http://host:port/customers/list Named Routes map.connect ‘home’, :controller => ‘customers’, :action => ‘list’ Default routes Map.connect ‘:controller/:action/:id’
Enterprise Deployment Nginx + mongrel Nginx + thin Apache + Passenger Apache + mongrel Capistrano
Capistrano – Rails Deployment Capify config/deploy.rb cap –T deploy cap deploy
Session Break Coffee ?
Advanced Topics Behavior Driven Development Test Driven Development Rspec Merb => Rails 3
Behaviour Driven Development Standard SDLC process defines this. Testing is done after development. Unit Testing Integration Testing Iterative cycle for development and testing. Testing is based on development and not requirements Takes more time.
Test Driven Development Part of Agile Testing and Development go on in parallel Actually Test Cases are developed before development !! Tests are based on requirements and not on development Development is focused on getting tests to pass ! 
Rspec Rspec for Models, Controllers and Views Books for Rspec are still being written ! A lot of specs are clear but clear guidance is missing still The Rspec Book – David Chleminsky
Nuances of Rspec Describe => the context or object It => test case Before and after code Helper routines can be added. Pending examples (??)
Rspec - Typical Example describe &quot;A new Account&quot; do it &quot;should have a balance of 0&quot; do account = Account.new account.balance.should == Money.new(0, :INR) end End # rspec A new Account - should have a balance 0
Rspec – Pending Examples Describe “Customer” do It “should have a address” It “should have name” It “should not be on terrorist list” Done Note that the it() does not have a code block
Before & After Code Before(:each) Before each it() executes Before(:all) Before all its() only once After (:each) After each (it) completes After (:all) After all its are complete
Before & after code example Describe Account do before(:each) @customer = Customer.create(‘Gautam’) @account = Account.create(@customer) end it “should have balance 0” do @account.balance.should == Money(0, :INR) end end
Helper Routines Describe Customer, “when risky” do def get_terror_list @terror_list = [ ‘Osama’, ‘Laden’, ‘Mahsood’ ] end it “should have balance 0” do get_terror_list @customer.include?(@terror_list).should be_empty end End
Rspec – further reading Shared Examples Nested Examples Spec::Mock objects Writing Views specs Writing Model specs Writing controller specs
Hands On! rails proj1 -d mysql cd proj1/ ./script/generate rspec ./script/generate rspec_model Stack ./script/generate rspec_controller Stack rake db:create:all RAILS_ENV=test rake db:migrate spec spec
References Books Rails Recipes – Chad Fowler http://www.pragprog.com/titles/fr_rr/rails-recipes Agile Web Development with Rails: http://www.pragprog.com/titles/rails2/agile-web-development-with-rails Internet resources http://api.rubyonrails.org http://rubyonrails.org/ http:// rubyonrails.org /documentation
Thank You!

Ruby On Rails

  • 1.
    Ruby On RailsGautam Rege Josh Software Pvt. Ltd.
  • 2.
    Speaker Introduction 9years Software Experience BE – PICT Working in rails since 2006 Co-founded Josh Software – 2007 Previous Experience Cybage, Zensar, Symantec
  • 3.
    Part – 1 Ruby on Rails Introduction
  • 4.
    History of RubyFather of Ruby – Yukihiro Matsumoto, a.k.a. “Matz”, Japan, 1995 Ruby is an Object Oriented Scripting Language Object Oriented helps in designing applications Scripting makes it faster and quicker to develop and redeploy.
  • 5.
    Ruby Vs PythonPython was the first OO script but its not a pure OO. There is no real encapsulation. Indentation !! def foo: print “This is the first line” print “This is second line” print “This is a syntax error” Serious Ruby Competitor Lots of python plugins and auto-install features Very popular today Caveats: Python – Why the name?
  • 6.
    Ruby Vs PerlPerl is really a procedural language. OO Perl was introduced later. Syntax difficult to understand: $ \ @ % Excellent stream parser.. That was the original purpose. Caveats: Perl - Practical Extraction and Report Language
  • 7.
    Ruby Vs Perlcontd.. foreach $item(@fields) {   if ($db{$item}) {   print &quot;conflict on $item\n&quot;;   $err ++;   next;   }  $db{$item} = \@fields;  } fields.each { |item| puts “conflict on #{item}” if fields.include?(item) }
  • 8.
    Features of RubyPure Object Oriented Script No indentation issues. Readable code. Blocks and Iterators Instance and Class variables Caveats: What is the difference between, Proc, Lamda, a normal function
  • 9.
    What do Ichoose anyway?? Perl is for people who believe that ‘old is gold’ and are set in their ways. Python is for ‘veterans’: people more comfortable on unix and vi than on Windows and Word! Ruby is for ‘enthusiasts’. You treat Ruby like you ‘pet’. You code because you enjoy it, watch it grow AND groom it as you like.
  • 10.
    Overall Comparison RailsPylons cgi/perl Web-frameworks    Plug-ins / auto-installation    Object Oriented Nature  Weak References (leaks)    Garbage Collection    Loose Data Typing    Data Types: Arrays, Hash Ruby Python Perl Features
  • 11.
    Web Technologies Java– J2EE Python – Pylons, CGI PHP Perl – CGI Ruby – Rails .NET – ASP, C#
  • 12.
    J2EE, .NET WebDevelopment J2EE. .NET are very evolved and very good for robust and heavy applications. They support different levels of tier architecture – EJB, databases Excellent Security – application and code Excellent Load Balancing and clustering support Deployment is complicated Development is slow Very expensive for commercial deployment
  • 13.
    CGI / Perl& PHP Simple architecture – so very fast WordPress is a PHP (XML-RPC) site Facebook Very difficult to support multi-tier architecture Security is weak Poor clustering support SQL centric code Typically procedural in nature Not suited for complicated web applications Very good for simple websites with small dynamic content
  • 14.
    Pylons Pylons isthe Python Web-framework Follows MVC pattern Relatively very new. Based on Rails architecture
  • 15.
    Ruby on RailsPure MVC framework Model View Controller Evolved over the past 4 years Authentication / Authorization very strong Being slowly adopted for heavy web applications
  • 16.
    Ruby On Railscontd.. Support simple multi-tier architecture Webserver Database Application Server Good clustering support with Nginx + thin, Apache + passenger Security at code level is weak i.e. no source code encryption support yet.
  • 17.
    Rails in theReal World Who uses Rails today? Twitter, Facebook Applications Vastly used as automated QA in large companies One of the pioneers of Agile Methodology JRuby – Java Ruby interpreter
  • 18.
    Part 2 –Rails Architecture
  • 19.
    Terminologies MVC Model- View – Controller Design Pattern REST Representational State Transfer ORM Object Relational Mapping Scaffold Building code skeletons. Migrations Managing the database tables and columns
  • 20.
    Model – View– Controller
  • 21.
    Model - OverviewMaintains state of an object / application. Manages the actual data involved. Validates object information In Rails: It is directly mapped to the database table via ORM It is independent of Database nuances. Models supports relationships Models have bulk of rails code ActiveRecord
  • 22.
    Controller – OverviewControl the logical flow of the request. Interact with model and render the views In Rails: Controllers manage authorization, sessions. Controllers decide how the request is processed. Render view according to business logic. ActionController
  • 23.
    View – OverviewViews are HTML renderers Render dynamic pages based on templates. XML Json HTML JS (Ajax) In Rails Should contain very less or NO logic Erb (Embedded Ruby ) is supported. ActionView
  • 24.
  • 25.
    Routing in Railshttp://host:port/:controller/:action/:id They determine Which controller Which action Which object Custom routes can also be setup.
  • 26.
    A word aboutRESTfull Rails Routes: map.resources :teams
  • 27.
  • 28.
    Part 2.1 ActiveRecordDatabase Connectors Mysql, pgsql, sqlite ORM Validations Relationships
  • 29.
    Object Relational MappingDatabase create table `customers` ( `id` int(11) auto_increment, `name` varchar(64), `age`int, primary key `id`) Model class Customer < ActiveRecord::Base end Object access cust = Customer.create puts “#{cust.name}, #{cust.age}”
  • 30.
    Database “rules” Ruleswould mean guidelines. They help in writing lesser code and allow easier access from Rails code All table names should be plural: customers, products, categories, people All tables should have `id` as primary key which is an auto_increment All tables should have ‘_id` suffix as foreign keys. Example: `customer_id` in `products` table
  • 31.
    Database “rules” contd..All datetime fields should have `_at` suffix. Example: `created_at` Avoid composite keys use model validations instead They are new supported in Rails 2.1.2 onwards Model name should be singular. Model Customer maps to `customers` table Model Category maps to `categories` table (!!) Model Person maps to `people` table (!!)
  • 32.
    Part 2.4 MigrationsMigrations are routines which help us manage the database. Versions are maintained in the database itself in a table called schema_migrations This controls relationships at model level and not database level. rake db:migrate
  • 33.
    Example of Migrationclass CreateAddresses < ActiveRecord::Migration def self.up create_table :addresses do |t| t.string :street t.integer :zip, :default => 0 t.references :customer t.timestamps end end def self.down drop_table :addresses end end This creates customer_id field in database. Relation between Customer and Address is determined by the models. i.e. class Customer has_one :address
  • 34.
    Rake Ruby buildprogram similar to ‘make’ Rakefiles (rake‘s version of Makefiles) are completely defined in standard Ruby syntax. No XML files to edit. No quirky Makefile syntax to worry about (tab or space issues!) rake –T in rails environment show default tasks User can add new tasks in lib/tasks/filename.rake It loads the rails environment – development, production or test or custom.
  • 35.
    Part 3 –Hands-on work Building a Rails Application
  • 36.
    Ruby on RailsInstallation Install ruby on Windows / Linux. Latest stable version: Ruby 1.8.6 , 1.8.7 Latest version: Ruby 1.9 http://rubyonrails.org/download Install rubygems Link: http:// rubyforge.org/frs/?group_id =126 Latest stable version: 1.3.3 gem install rails Latest stable version: 2.3.2 Recommended: 2.1.2 Install MySQL 5.x Link: http://dev.mysql.com/downloads/mysql/5.1.html#downloads
  • 37.
    Setup the EnvironmentEnsure installation is good and versions are correct. ruby –v >= 1.8.6 gem –v >= 1.3.2 rails –v >= 2.1.0 mysql –version >= 5.0.x Editor: Scite Create the rails project cmd> rails <name> -d mysql
  • 38.
    Rails Project Layout..../app ......../controller ......../helpers ......../models ......../views ............/layouts ..../config ..../components ..../db ..../doc ..../lib ..../log ..../public ..../script ..../test ..../tmp ..../vendor ......../plugins Core Application code: Controllers, Helpers, Models, Views Configuration for database, initializers,routes Database migrations Additional or custom libraries, rake tasks etc. The HTDOC for this web project. This contains JS, CSS, images etc. External plugins for this project.
  • 39.
  • 40.
    ActiveRecord Validations validateGeneric validation method that can be used for custom validation validates_uniqueness_of :name validates_numericality_of :age validates_presence_of :address validates_format_of :email, :with => <regex>
  • 41.
    ActiveRecord Callbacks before_createafter_create before_save after_save before_update after_update before_destroy after_destroy before_validation after_validation
  • 42.
    ActiveRecord Relations has_many1 ↔ m relationship with child belongs_to 1 ↔ 1 relationship with parent has_one 1 ↔ 1 relationship with child has_many :through => Earlier versions: has_and_belongs_to_many m ↔ m relationship with peer
  • 43.
    Database revisit createtable `customers` ( `id` int(11) auto_increment, `name` varchar(64), `age`int, primary key `id`) create table `addresses` ( `id` int(11) auto_increment, `street` varchar(64), `zip_code` varchar(64), `customer_id` int, foreign key customer_id references customer(id) primary key `id`) This line is actually not necessary in Rails as migrations handle this.
  • 44.
    has_one ↔ belongs_to class Customer < ActiveRecord::Base has_one :address end class Address < ActiveRecord::Base belongs_to :customer end cust = Customer.new(:name => ‘Gautam Rege’) address = Address.new(:customer => cust, :street => ‘SB Road’, :zip => ‘411016’) cust.address => #<Address object> address.customer => # <Customer object> Cust.address.zip => Zip code of address for this customer
  • 45.
    Database revisit createtable `bank_accounts` ( `id` int(11) auto_increment, `acc_number` varchar(64), `branch` varchar(64), `customer_id` int, foreign key customer_id references customer(id) primary key `id`)
  • 46.
    has_many ↔ belongs_to class Customer < ActiveRecord::Base has_many :bank_accounts end class BankAccount < ActiveRecord::Base belongs_to :customer end cust = Customer.new(:name => ‘Gautam Rege’) bank = BankAccount.new(:customer => cust, :acc_number => ‘123456’, :branch => ‘XYZ’) cust.bank_accounts =>[ #<BankAccount object> array ] bank.customer => # <Customer object> Camelization !!
  • 47.
    Database Revist createtable `products` ( `id` int(11) auto_increment, `cost` varchar(64), primary key `id`) create table `categories` ( `id` int(11) auto_increment, `name` varchar(64), primary key `id`) create table `product_categories` ( `id` int(11) auto_increment, `product_id` int, `category_id` int primary key `id`)
  • 48.
    has_many :through =>class Customer < ActiveRecord::Base has_many :bank_account_customers has_many :bank_accounts :through => :bank_account_customers end class BankAccount < ActiveRecord::Base has_many : bank_account_customers has_many :customers :through => : bank_account_customers end class BankAccountCustomer < ActiveRecord::Base belongs_to :bank_account belongs_to :customer end customer.bank_accounts => [ #<BankAccount object> array ] acc.customers => [ #<Customer object> array ]
  • 49.
    Named Scopes ActiveRecord::NamedScope::ScopeA scope represents a narrowing of a database query Returns a collection but its not an Array. It resembles the association object constructed by a has_many declaration Unlike arrays, They are “composable” - named_scopes can be chained!
  • 50.
    Named Scope exampleclass Customer < ActiveRecord::Base has_many :bank_accounts named_scope :hni, :conditions => [ ‘hni = ?’ true ] named_scope :high_risk lambda do | list | { :joins => ‘risk_customer_lists’, :conditions => [‘name in (?)’, list ] } End @customers = Customer.hni @customers = Customer.hni @customers = @customers.high_risk(terrorists) @customers = Customer.hni.high_risk(terrorists)
  • 51.
    Hands On! Creating& updating migrations Adding relationships Rails console Rails dbconsole
  • 52.
  • 53.
    Part 2.2 ActionControllerRails HTTP request processing Helpers Filters Accessing the models Rendering the views
  • 54.
    Processing a HTTPRails request http:// host:port /:controller/:action/:id http://some.url:3000/customer/show/1 “ _controller” suffix in app/controllers customers_controller.rb All actions are mapped as functions in the controller. “def show” params[:id] = 1 All views default to app/views/<controller>/<action>.erb.html app/views/customers/show.html.erb
  • 55.
    Helpers Helpers arenot classes but modules. They mainly assist views with some helper functions and global etc. Helper methods are accessible in controllers and views. Hmm.. Why are helpers not available to the model?
  • 56.
    Filters before_filter, after_filterare controller class methods Filters can be used to check authentication, caching, or auditing before the intended action is performed. Filters have access to the request, response headers class CustomerController < ApplicationController before_filter :login_required, :except => [:list, :show] def login_required # check if user is logged in end end
  • 57.
    ActionController example app/controllers/customer_controller.rb:class CustomerController < ApplicationController def index # default function when no action is called. :redirect_to :action => ‘list’ end def list @customers = Customer.find(:all) end def show @customer = Customer.find(params[:id]) end end GET and POST parameters are accessed via params
  • 58.
    Part 2.3 ActionViewEmbedded Ruby (erb) Rails Magic Instance variables (@variables) are copied into and ActionView instance before view invocation That is why all instance variables created in ActionController are available ‘as is’ to the views.
  • 59.
    Partials Partials areviews which can be rendered in other views. They are always stored with a ‘_’ prefix _form.erb.html :render :partial => ‘form’
  • 60.
    Layouts The basicpage layout for all pages. Default layout: application.erb.html Layout can be changed by specifying ‘layout <name>’ in the controller.
  • 61.
    Rendering Views EmbeddedRuby code without rendering <% %> Rendering dynamic data <%= %> Example: <% @customers.each do |cust| %> Name: <%= cust.name %> <% end %>
  • 62.
    FormHelpers <% form_for:customer @customer :url => {:action => :create} do |f| %> <%= f.text_field :name %> <%= f.date_select :birth_date %> <%= submit_tag 'Create' %> <% end %>
  • 63.
    Ajax on RailsLink_to_remote Remote_form_for Rails supports different rendering formats Html Xml Js json
  • 64.
  • 65.
    Building a RailsApplication Installing Ruby, rubygems and Rails Rails Project Layout Design the application Write Migrations Generate Scaffold Deploy & Run Rails helps you build web applications really fast but YOU STILL HAVE TO DESIGN IT !!
  • 66.
    Application Idea?? Letsthink of one now Pre-decided
  • 67.
    Survey Application Asurvey is a set of questions which a user answers Application should have multiple surveys and a user should be able to choose any survey. User should be able to see all the questions in the survey. User should be able to answer one or more questions. User can choose to leave some questions un-answered. All answers are free-text
  • 68.
    Survey Application Resultof the survey for a user should be shown. User can edit his previous answer to some question in a survey Anyone can see the results of the survey for any user. There is no need of any authentication.
  • 69.
    Is the abovetoo easy ??  Questions can be free-text or multiple choice. User authorization User should be able to change only his/her answers later Statistical survey data How many users took which survey? Most popular survey User with maximum surveys
  • 70.
    Survey Application surveyquestions answers users
  • 71.
    Relationships A surveyhas_many questions A question has_many answers A user has_many answers A user has_many surveys A survey has_many users
  • 72.
    Migrations Survey Migrationt.string :name User Migration T.string :name User_surveys T.references :user T.references :survey
  • 73.
    Migrations contd.. QuestionsMigration T.string value T.references :survey Answer migration T.string :value T.references :question T.references :user
  • 74.
    Scaffolding Generate scaffolds./script/generate scaffold Customer This generates the model, controller, helper and migration for customer app/models/customer.rb app/controllers/customers_controller.rb App/helpers/customer_helper.rb App/views/customers/*.erb.html Db/migrate/<version>_create_customers.rb
  • 75.
    Checklist Migrations completed?Model relationships added? Config/database.yml correct? Database created? rake db:create rake db:migrate Server started?
  • 76.
    Actual Development (finally)Add code to controller Add validation to models Modify the views Adding some CSS and JS
  • 77.
  • 78.
    Deploying the applicationStarting rails server RAILS_ROOT/script/start Stopping the application ^C URL: http://localhost:3000 Production Deployment ./script/server -eproduction
  • 79.
    Configuring routes ResourceMaps map.resources :customer => Customer route http://host:port/customers/new http://host:port/customers/show http://host:port/customers/list Named Routes map.connect ‘home’, :controller => ‘customers’, :action => ‘list’ Default routes Map.connect ‘:controller/:action/:id’
  • 80.
    Enterprise Deployment Nginx+ mongrel Nginx + thin Apache + Passenger Apache + mongrel Capistrano
  • 81.
    Capistrano – RailsDeployment Capify config/deploy.rb cap –T deploy cap deploy
  • 82.
  • 83.
    Advanced Topics BehaviorDriven Development Test Driven Development Rspec Merb => Rails 3
  • 84.
    Behaviour Driven DevelopmentStandard SDLC process defines this. Testing is done after development. Unit Testing Integration Testing Iterative cycle for development and testing. Testing is based on development and not requirements Takes more time.
  • 85.
    Test Driven DevelopmentPart of Agile Testing and Development go on in parallel Actually Test Cases are developed before development !! Tests are based on requirements and not on development Development is focused on getting tests to pass ! 
  • 86.
    Rspec Rspecfor Models, Controllers and Views Books for Rspec are still being written ! A lot of specs are clear but clear guidance is missing still The Rspec Book – David Chleminsky
  • 87.
    Nuances of RspecDescribe => the context or object It => test case Before and after code Helper routines can be added. Pending examples (??)
  • 88.
    Rspec - TypicalExample describe &quot;A new Account&quot; do it &quot;should have a balance of 0&quot; do account = Account.new account.balance.should == Money.new(0, :INR) end End # rspec A new Account - should have a balance 0
  • 89.
    Rspec – PendingExamples Describe “Customer” do It “should have a address” It “should have name” It “should not be on terrorist list” Done Note that the it() does not have a code block
  • 90.
    Before & AfterCode Before(:each) Before each it() executes Before(:all) Before all its() only once After (:each) After each (it) completes After (:all) After all its are complete
  • 91.
    Before & aftercode example Describe Account do before(:each) @customer = Customer.create(‘Gautam’) @account = Account.create(@customer) end it “should have balance 0” do @account.balance.should == Money(0, :INR) end end
  • 92.
    Helper Routines DescribeCustomer, “when risky” do def get_terror_list @terror_list = [ ‘Osama’, ‘Laden’, ‘Mahsood’ ] end it “should have balance 0” do get_terror_list @customer.include?(@terror_list).should be_empty end End
  • 93.
    Rspec – furtherreading Shared Examples Nested Examples Spec::Mock objects Writing Views specs Writing Model specs Writing controller specs
  • 94.
    Hands On! railsproj1 -d mysql cd proj1/ ./script/generate rspec ./script/generate rspec_model Stack ./script/generate rspec_controller Stack rake db:create:all RAILS_ENV=test rake db:migrate spec spec
  • 95.
    References Books RailsRecipes – Chad Fowler http://www.pragprog.com/titles/fr_rr/rails-recipes Agile Web Development with Rails: http://www.pragprog.com/titles/rails2/agile-web-development-with-rails Internet resources http://api.rubyonrails.org http://rubyonrails.org/ http:// rubyonrails.org /documentation
  • 96.