Sunday, September 6, 2009

Ubuntu 9.04 : Upgrading from Rails 2.3.3 to Rails 2.3.4

This is how I have upgraded Rails 2.3.3 to Rails 2.3.4 in Ubuntu 9.04

chee@ibm4linux:~$ sudo gem install rails
[sudo] password for chee:
Successfully installed activesupport-2.3.4
Successfully installed activerecord-2.3.4
Successfully installed actionpack-2.3.4
Successfully installed actionmailer-2.3.4
Successfully installed activeresource-2.3.4
Successfully installed rails-2.3.4
6 gems installed
Installing ri documentation for activesupport-2.3.4...
Installing ri documentation for activerecord-2.3.4...
Installing ri documentation for actionpack-2.3.4...
Installing ri documentation for actionmailer-2.3.4...
Installing ri documentation for activeresource-2.3.4...
Installing ri documentation for rails-2.3.4...
Installing RDoc documentation for activesupport-2.3.4...
Installing RDoc documentation for activerecord-2.3.4...
Installing RDoc documentation for actionpack-2.3.4...
Installing RDoc documentation for actionmailer-2.3.4...
Installing RDoc documentation for activeresource-2.3.4...
Installing RDoc documentation for rails-2.3.4...

Announcement : Rails 2.3.4 is released on 4th Sept 2009

The Rails Team has just announced the release of Rails 2.3.4 as follows :-

We’ve released Ruby on Rails 2.3.4, this release fixes bugs and introduces a few minor features. Due to the inclusion of two security fixes, all users of the 2.3 series are recommended to upgrade as soon as possible.

Security Fixes

2.3.4 contains fixes for two security issues which were reported to us. For more details see the security announcements:

Bug Fixes

Thanks to the success of the BugMash we have around 100 bug fixes as part of this release. Of particular not is the fix to reloading problems related to rack middleware and rails metals when running in development mode.

New Features

  • Support for bundling I18n translations in plugins, Rails will now automatically add locale files found in any engine’s locale directory to the I18n.load_path. commit
  • Added db/seeds.rb as a default file for storing seed data for the database. Can be loaded with rake db:seed commit

Rails Basics : link_to

It is an almost Rails convention that you should use Ruby code rather than HTML to create links as a mater of style and flexibility via routes.rb

link_to is an example of a Rails function  for html generation and is typically used to add site-wide navigation. For example,

   <%= link_to('Home',       { :action = 'index'}) %> |
   <%= link_to('About Us', { :action ='about'}) %>

You may be interested to note that curly braces are optional in hashes where they are the final argument to a function as follows :-

   <%= link_to('About Us',:action ='about') %>

How does one not link to a page that is currently displayed ?

   <%= link_to_unless_current('Home',       { :action = 'index'}) %> |
   <%= link_to_unless_current('About Us', { :action ='about'}) %>

Are there other related link_to functions ?

Rails adheres to a naming convention whereby a group of related functions have related names, usually of the form original_function_name and original_function_name_with_modification

Let's check to the Rails API via the Rails API Tab in Aptana Radrails or  at http://api.rubyonrails.org and this is what you should find

  • link_to
  • link_to_if
  • link_to_remote
  • link_to_unless
  • link_to_unless_current
How to display an image inside a link_to

<%= link_to image_tag("about.gif", :border=>0), :action => 'about' %>

Wednesday, September 2, 2009

Rail Basics : What happens when you script/generate ?

chee@ibm4linux:~/workspace/crm4test$ script/generate

Usage: script/generate generator [options] [args]
Rails Info:
    -v, --version                    Show the Rails version number and quit.
    -h, --help                       Show this help message and quit.
General Options:
    -p, --pretend                    Run but do not make any changes.
    -f, --force                      Overwrite files that already exist.
    -s, --skip                       Skip files that already exist.
    -q, --quiet                      Suppress normal output.
    -t, --backtrace                  Debugging: show backtrace on errors.
    -c, --svn                        Modify files with subversion. (Note: svn must be in path)
    -g, --git                        Modify files with git. (Note: git must be in path)


Installed Generators
  Plugins (vendor/plugins): authenticated, roles
  Builtin: controller, helper, integration_test, mailer, metal, migration, model, observer, performance_test, plugin, resource, scaffold, session_migration

More are available at http://wiki.rubyonrails.org/rails/pages/AvailableGenerators
  1. Download, for example, login_generator.zip
  2. Unzip to directory /home/chee/.rails/generators/login
     to use the generator with all your Rails apps
     or to /home/chee/workspace/crm4test/lib/generators/login
     to use with this app only.
  3. Run generate with no arguments for usage information
       script/generate login

Generator gems are also available:
  1. gem search -r generator
  2. gem install login_generator
  3. script/generate login

Rails Basics : What happens when you script/generate model ?

chee@ibm4linux:~/workspace/crm4test$ script/generate model

Usage: script/generate model ModelName [field:type, field:type]
Options:
        --skip-timestamps            Don't add timestamps to the migration file for this model
        --skip-migration             Don't generate a migration file for this model
        --skip-fixture               Don't generation a fixture file for this model
Rails Info:
    -v, --version                    Show the Rails version number and quit.
    -h, --help                       Show this help message and quit.
General Options:
    -p, --pretend                    Run but do not make any changes.
    -f, --force                      Overwrite files that already exist.
    -s, --skip                       Skip files that already exist.
    -q, --quiet                      Suppress normal output.
    -t, --backtrace                  Debugging: show backtrace on errors.
    -c, --svn                        Modify files with subversion. (Note: svn must be in path)
    -g, --git                        Modify files with git. (Note: git must be in path)

Description:
    Stubs out a new model. Pass the model name, either CamelCased or
    under_scored, and an optional list of attribute pairs as arguments.

    Attribute pairs are column_name:sql_type arguments specifying the
    model's attributes. Timestamps are added by default, so you don't have to
    specify them by hand as 'created_at:datetime updated_at:datetime'.

    You don't have to think up every attribute up front, but it helps to
    sketch out a few so you can start working with the model immediately.

    This generates a model class in app/models, a unit test in test/unit,
    a test fixture in test/fixtures/singular_name.yml, and a migration in
    db/migrate.

Examples:
    `./script/generate model account`

        creates an Account model, test, fixture, and migration:
            Model:      app/models/account.rb
            Test:       test/unit/account_test.rb
            Fixtures:   test/fixtures/accounts.yml
            Migration:  db/migrate/XXX_add_accounts.rb

    `./script/generate model post title:string body:text published:boolean`

        creates a Post model with a string title, text body, and published flag.

Monday, August 31, 2009

Rails Plugins : How to Install role_requirement ?

Step 1 - Grab role_requirement form github.com

chee@ibm4linux:~/workspace/crm4test$ script/plugin install git://github.com/timcharper/role_requirement.git

Result 

Initialized empty Git repository in /home/chee/workspace/crm4test/vendor/plugins/role_requirement/.git/
remote: Counting objects: 32, done.
remote: Compressing objects: 100% (30/30), done.
remote: Total 32 (delta 3), reused 10 (delta 0)
Unpacking objects: 100% (32/32), done.
From git://github.com/timcharper/role_requirement
 * branch            HEAD       -> FETCH_HEAD

Step 2 - Run the generator

chee@ibm4linux:~/workspace/crm4test$ script/generate roles Role User

Generating Role against User
Added the following to the top of app/models/user.rb:
 
  # ---------------------------------------
  # The following code has been generated by role_requirement.
  # You may wish to modify it to suit your need
  has_and_belongs_to_many :roles
 
  # has_role? simply needs to return true or false whether a user has a role or not. 
  # It may be a good idea to have "admin" roles return true always
  def has_role?(role_in_question)
    @_list ||= self.roles.collect(&:name)
    return true if @_list.include?("admin")
    (@_list.include?(role_in_question.to_s) )
  end
  # ---------------------------------------

 
Added ApplicationController include to /home/chee/workspace/crm4test/app/controllers/application_controller.rb
Added RoleRequirement include to /home/chee/workspace/crm4test/app/controllers/application_controller.rb
      create  test/fixtures/roles.yml
      create  app/models/role.rb
      create  lib/role_requirement_system.rb
      create  lib/role_requirement_test_helper.rb
      create  lib/hijacker.rb
      exists  db/migrate
      create  db/migrate/20090831042625_create_roles.rb


Step 3 - rake db:migrate

chee@ibm4linux:~/workspace/crm4test$ rake db:migrate
(in /home/chee/workspace/crm4test)
==  CreateRoles: migrating ====================================================
-- create_table("roles")
   -> 0.0037s
-- create_table("roles_users", {:id=>false})
   -> 0.0027s
-- add_index("roles_users", "role_id")
   -> 0.0122s
-- add_index("roles_users", "user_id")
   -> 0.0016s
==  CreateRoles: migrated (0.0229s) ===========================================


What does the Generators do ?  
  • Only if many roles are used:
    • Generates habtm table, creates role.rb with the habtm declaration. Adds declaration in user.rb (scans the code for "class User < ActiveRecord::Base", and puts the new code right after it.
    • Creates an admin user in users.yml, with a role named admin in roles.yml, including a fixture to demonstrate how to relate roles to users in roles_users.yml
  • Modify the user.rb (or corresponding user model) file, add the instance method has_role?
  • Generates RoleRequirementSystem against for the corresponding user model.
  • Generates a migration to make the necessary database changes
  • Scans ApplicationController, inserts the lines "include AuthenticatedSystem", and "include RoleRequirementSystem", if not already included.
  • Scans test_helper.rb and adds "includes RoleRequirementTestHelpers", if not already included.

 

Rails Plugins : How to Install restful_authentication ?

To use role_requirement, the prerequisite is to install the restful_authentication plugin. These are the 3 steps that I took to achieve a succesful installation.

Step 1 - Grab the plugin from github.com


chee@ibm4linux:~/workspace/crm4test$ script/plugin install git://github.com/technoweenie/restful-authentication.git

Result

Initialized empty Git repository in /home/chee/workspace/crm4test/vendor/plugins/restful-authentication/.git/
remote: Counting objects: 89, done.
remote: Compressing objects: 100% (77/77), done.
remote: Total 89 (delta 5), reused 31 (delta 2)
Unpacking objects: 100% (89/89), done.
From git://github.com/technoweenie/restful-authentication
 * branch            HEAD       -> FETCH_HEAD

Step 2 - Generate user and sessions controllers

chee@ibm4linux:~/workspace/crm4test$ script/generate authenticated user sessions

This is what you will see in the command line editor (in Ubuntu 9.04, a Gnome Terminal Window)

Ready to generate.
----------------------------------------------------------------------
Once finished, don't forget to:

- Add routes to these resources. In config/routes.rb, insert routes like:
    map.signup '/signup', :controller => 'users', :action => 'new'
    map.login  '/login',  :controller => 'sessions', :action => 'new'
    map.logout '/logout', :controller => 'sessions', :action => 'destroy'

CCH : No need to do so as the latest version automatically includes these routes to routes.rb
 ----------------------------------------------------------------------

We've create a new site key in config/initializers/site_keys.rb.  If you have existing
user accounts their passwords will no longer work (see README). As always,
keep this file safe but don't post it in public.

----------------------------------------------------------------------
      exists  app/models/
      exists  app/controllers/
      exists  app/controllers/
      exists  app/helpers/
      create  app/views/sessions
      exists  app/controllers/
      exists  app/helpers/
      create  app/views/users
      exists  config/initializers
      exists  test/functional/
      exists  test/functional/
      exists  test/unit/
      exists  test/fixtures/
      create  app/models/user.rb
      create  app/controllers/sessions_controller.rb
      create  app/controllers/users_controller.rb
      create  lib/authenticated_system.rb
      create  lib/authenticated_test_helper.rb
      create  config/initializers/site_keys.rb
      create  test/functional/sessions_controller_test.rb
      create  test/functional/users_controller_test.rb
      create  test/unit/user_test.rb
      create  test/fixtures/users.yml
      create  app/helpers/sessions_helper.rb
      create  app/helpers/users_helper.rb
      create  app/views/sessions/new.html.erb
      create  app/views/users/new.html.erb
      create  app/views/users/_user_bar.html.erb
      exists  db/migrate
      create  db/migrate/20090831032706_create_users.rb
       route  map.resource :session
       route  map.resources :users
       route  map.signup '/signup', :controller => 'users', :action => 'new'
       route  map.register '/register', :controller => 'users', :action => 'create'
       route  map.login '/login', :controller => 'sessions', :action => 'new'
       route  map.logout '/logout', :controller => 'sessions', :action => 'destroy'

Step 3 - Modify the Project Database 

chee@ibm4linux:~/workspace/crm4test$ rake db:migrate
(in /home/chee/workspace/crm4test)
==  CreateUsers: migrating ====================================================
-- create_table("users", {:force=>true})
   -> 0.0074s
-- add_index(:users, :login, {:unique=>true})
   -> 0.0374s
==  CreateUsers: migrated (0.0464s) ===========================================

You may be interested to look at the contents of the migration file as follows :-

class CreateUsers < ActiveRecord::Migration
  def self.up
    create_table "users", :force => true do |t|
      t.column :login, :string, :limit => 40
      t.column :name, :string, :limit => 100, :default => '', :null => true
      t.column :email, :string, :limit => 100
      t.column :crypted_password,          :string, :limit => 40
      t.column :salt,     :string, :limit => 40
      t.column :created_at,  :datetime
      t.column :updated_at, :datetime
      t.column :remember_token, :string, :limit => 40
      t.column :remember_token_expires_at, :datetime


    end
    add_index :users, :login, :unique => true
  end

  def self.down
    drop_table "users"
  end
end

The Generated User & Sessions Controllers

User.rb

class UsersController < ApplicationController
  # Be sure to include AuthenticationSystem in Application Controller instead
  include AuthenticatedSystem
 

  # render new.rhtml
  def new
    @user = User.new
  end

  def create
    logout_keeping_session!
    @user = User.new(params[:user])
    success = @user && @user.save
    if success && @user.errors.empty?
            # Protects against session fixation attacks, causes request forgery
      # protection if visitor resubmits an earlier form using back
      # button. Uncomment if you understand the tradeoffs.
      # reset session
      self.current_user = @user # !! now logged in
      redirect_back_or_default('/')
      flash[:notice] = "Thanks for signing up!  We're sending you an email with your activation code."
    else
      flash[:error]  = "We couldn't set up that account, sorry.  Please try again, or contact an admin (link is above)."
      render :action => 'new'
    end
  end
end

sessions.rb

# This controller handles the login/logout function of the site. 
class SessionsController < ApplicationController
  # Be sure to include AuthenticationSystem in Application Controller instead
  include AuthenticatedSystem

  # render new.rhtml
  def new
  end

  def create
    logout_keeping_session!
    user = User.authenticate(params[:login], params[:password])
    if user
      # Protects against session fixation attacks, causes request forgery
      # protection if user resubmits an earlier form using back
      # button. Uncomment if you understand the tradeoffs.
      # reset_session
      self.current_user = user
      new_cookie_flag = (params[:remember_me] == "1")
      handle_remember_cookie! new_cookie_flag
      redirect_back_or_default('/')
      flash[:notice] = "Logged in successfully"
    else
      note_failed_signin
      @login       = params[:login]
      @remember_me = params[:remember_me]
      render :action => 'new'
    end
  end

  def destroy
    logout_killing_session!
    flash[:notice] = "You have been logged out."
    redirect_back_or_default('/')
  end

protected
  # Track failed login attempts
  def note_failed_signin
    flash[:error] = "Couldn't log you in as '#{params[:login]}'"
    logger.warn "Failed login for '#{params[:login]}' from #{request.remote_ip} at #{Time.now.utc}"
  end
end

Welcome to Rails.. Rails... Rails !

In 1995, I started the popular Clipper...Clipper... Clipper website (no blogs then) which was very popular and linked by virtually every Clipper-related site. When I switched to Windows via Delphi in 1997, I started the Delphi... Delphi... Delphi site. In June 2007, I discovered Ruby on Rails and no prize for guessing what I am gonna name this blog. which I started on 2nd October 2007.

As at 10th June 2010, we have 13,364 unique visitors from more than 84 countries such as Angola, Andorra, Argentina, Australia, Austria, Algeria,Barbados, Bosnia and Herzogovina, Belgium, Brazil, Bulgaria, Bangladesh, Belarus, Bolivia, Chile, Cambodia, Cape Vede, Canada, China, Colombia, Costa Rica, Croatia, Cyprus, Czech Republic, Denmark, Egypt, Estonia, Finland, France, Guadeloupe, Guatemala, Germany, Greece, Hong Kong, Hungary, India, Indonesia, Ireland, Israel, Italy, Japan, Kenya, Korea, Lithuania, Latvia, Malaysia, Mexico, Macao, Netherlands, Nepal, Norway, New Zealand, Oman, Panama, Peru, Poland, Portugal,Paraguay , Philippines, Romania, Russian Federation, Saudi Arabia, Singapore, Spain, Slovakia, Slovenia, Serbia, South Korea, Slovenia, South Africa, Spain, Switzerland, Sri Lanka, Sweden, Taiwan, Thailand, Turkey, United Arab Emirates, Ukraine, USA, UK, Venezuela, Vietnam

CCH
10th June 2010, 19:42