Rails - tlam/Wiki GitHub Wiki

Rails 3 under development environment

  1. Install rvm

  2. From your rails project, install your gems to vendor/bundle

     bundle install --path vendor/bundle
    
  3. In your rails project, there will be a file called .bundle/config created which will have:

     ---
     BUNDLE_PATH: vendor/bundle
     BUNDLE_DISABLE_SHARED_GEMS: '1'
    
  4. Start rails from script/rails which will use gems from vendor/bundle:

     script/rails s
    

NOTE: The above is similar to Python's virtualenv in isolating specific library versions to a specific location

Rails starting

  1. Starts a new project:

     rails project -d postgresql
    
  2. Configure your database connection settings, edit:

     project/config/database.yml
    
  3. Create your database:

     rake db:create
    
  4. Generate controller:

     rails generate controller home index
    
  5. Scaffold:

     rails generate scaffold Post name:string title:string content:text
    
  6. The types supported by Active Record are

     :primary_key, :string, :text, :integer, :float, :decimal, :datetime, 
     :timestamp, :time, :date, :binary, :boolean</pre>
    
  7. Run a specific unit test from your project folder:

     rake test:units TEST=test/unit/your_model_test.rb
    
  8. Check for pending migrations:

     rake db:abort_if_pending_migrations
    
  9. Generate a migration stub file:

     rails generate migration AddCityToPerson
    
  10. Load all fixtures:

     rake db:fixtures:load
    
  11. Load a specific fixture

     rake db:fixtures:load FIXTURES=your_fix.yml
    
  12. View all routes

     rake routes
    
  13. Run a script under the Rails environment where test.rb is at the project root folder:

     script/rails runner "eval(File.read 'test.rb')"
    
  14. Rake under a specific environment:

     rake db:schema:load RAILS_ENV=staging
    
  15. Running the console under a custom staging environment:

     script/rails c staging
    

Generic Authentication

  1. Scaffold the User

     rails generate scaffold User name:string hashed_password:string salt:string
    
  2. Create app/controllers/admin_controller.rb

     class AdminController < ApplicationController
       before_filter :authenticate, :except => :login
    
       def login
         session[:user_id] = nil
         if request.post?
           user = User.authenticate(params[:name], params[:password])
           if user
             session[:user_id] = user.id
             uri = session[:original_uri]
             session[:original_uri] = nil
             redirect_to(uri || { :action => 'index' })
           else
             flash.now[:notice] = 'Invalid user/password combination'
           end
         end
       end
    
       def logout
         session[:user_id] = :logged_out
         flash[:notice] = "Logged out"
         redirect_to(:action => "login")
       end
     end
    
  3. Add the following to app/controllers/application_controller.rb

     class ApplicationController < ActionController::Base
       before_filter :authenticate, :except => [:index, :show]
       protect_from_forgery
    
     protected
       def authenticate
         unless User.find_by_id(session[:user_id])
           session[:original_uri] = request.request_uri
           flash[:notice] = 'Please log in'
           redirect_to :controller => 'admin', :action => 'login'
         end
       end
     end
    
  4. User model app/models/user.rb

     require 'digest/sha1'
    
     class User < ActiveRecord::Base
       validates_presence_of :name
       validates_uniqueness_of :name
    
       attr_accessor :password_confirmation
       validates_confirmation_of :password
       validate :password_non_blank
    
       def self.authenticate(name, password)
         user = self.find_by_name(name)
         if user
           expected_password = encrypted_password(password, user.salt)
           if user.hashed_password != expected_password
             user = nil
           end
         end
         user
       end
    
       # 'password' is a virtual attribute
       def password
         @password
       end
    
       def password=(pwd)
         @password = pwd
         return if pwd.blank?
         create_new_salt
         self.hashed_password = User.encrypted_password(self.password, self.salt)
       end
    
     private
       def password_non_blank
         errors.add(:password, 'Missing password') if hashed_password.blank?
       end
    
       def self.encrypted_password(password, salt)
         string_to_hash = password + 'wibble' + salt
         Digest::SHA1.hexdigest(string_to_hash)
       end
    
       def create_new_salt
         self.salt = self.object_id.to_s + rand.to_s
       end
     end
    
  5. Update your config/routes.rb

     match 'admin' => 'admin#index'
     match 'login' => 'admin#login', :as => 'login'
     match 'logout' => 'admin#logout'
    
  6. Login view app/views/admin/login.html.erb

     <div class="depot-form">
       <% form_tag(login_path, :method => "post") do %>
         <fieldset>
           <legend>Please Log In</legend>
           <div>
             <label for="name">Name:</label>
             <%= text_field_tag :name, params[:name] %>
           </div>
    
           <div>
             <label for="password">Password:</label>
             <%= password_field_tag :password, params[:password] %>
           </div>
    
           <div>
             <%= submit_tag "Login" %>
           </div>
         </fieldset>
       <% end %>
     </div>
    
⚠️ **GitHub.com Fallback** ⚠️