Post on 10-May-2015
description
Turbocharge your web development with Rails
Vagmi MudumbaiDharana Software Innovations Pvt Ltd
@vagmi / vagmi@dharanasoft.com
About mehttp://vagmim.com
RailsPundit
ChennaiGeeksfacebook.com/groups/chennaigeeks
http://www.catb.org/~esr/hacker-emblem/
Agenda
• About Ruby
• About Rails
• MVC
• Models
• Relationships
• Routes
• Controllers
• Layouts
• Views
• Forms
• Q & A
•Created by Yakuhiro “Matz” Matsumoto in 1995 in Japan
•Generally available to the english speaking world at 2000
•Multi paradigm language
•Supports imperative/Object Oriented/Functional styles of programming
# The Greeter classclass Greeter def initialize(name) @name = name.capitalize end
def salute puts "Hello #{@name}!" endend
# Create a new objectg = Greeter.new("world")
# Output "Hello World!"g.salute
•Many Flavors
•MRI/YARV
•JRuby
•Rubinius
•IronRuby
•Maglev
•And more
•Created in 2005 by David Heinemeier Hannson (a.k.a. DHH)•A web framework to helps you actually enjoy programming
• Intended to be simple and consistent to use•Convention over configuration•Freedom from needless XML situps
Installing Ruby
• For windows you can get Ruby from
• http://rubyinstaller.org/
Installing Ruby
• For Linux and Mac OSX
• Install via RVM
• http://rvm.beginrescueend.com/
• http://amerine.net/2010/02/24/rvm-rails3-ruby-1-9-2-setup.html
Installing Rails
$ gem install rails
Rails MVC
Router
Controller
ModelView DBHTML/CSS/JS
Create a Rails App
$ rails new todolist
Rails Project Structuremyapp/|-- Gemfile # all the dependencies go here|-- Rakefile # the build file??|-- app # The entire application sits here|-- config # Configure the app to your heart's content|-- db # Database migrations, seed file|-- lib # Custom rake tasks and your libraries|-- log # The directory we all love|-- public # Static assets like CSS, JS and images|-- script # Contains one file "rails"|-- test # Tests - unit, functional, integration|-- tmp # misc stuff like sessions, pids and working files`-- vendor # 3rd party stuff - not used as much these days
Rails Project Structure
myapp/`-- app |-- controllers # controllers | `-- application_controller.rb |-- helpers | `-- application_helper.rb # view helpers |-- mailers |-- models `-- views `-- layouts `-- application.html.erb # could be haml or any other # templating language
Rails Project Structuremyapp/`-- config |-- application.rb # the main application config file |-- boot.rb # setup bundler and the environment |-- database.yml # setup database connections |-- environments | |-- development.rb # development specific setup | |-- production.rb # production specific setup | `-- test.rb # test specific setup |-- initializers | |-- inflections.rb # any file put inside | |-- mime_types.rb # this directory will | |-- secret_token.rb # be executed when the | `-- session_store.rb # rails application boots |-- locales | `-- en.yml # setup internationalization `-- routes.rb # map URLs to Controllers/Actions
Models
Create a model
$ rails g model todo title:string done:boolean completed_at:datetime invoke active_record create db/migrate/20110625034305_create_todos.rb create app/models/todo.rb invoke test_unit create test/unit/todo_test.rb create test/fixtures/todos.yml
Migration
class CreateTodos < ActiveRecord::Migration def self.up create_table :todos do |t| t.string :title t.boolean :done t.datetime :completed_at
t.timestamps end end
def self.down drop_table :todos endend
The model class
class Todo < ActiveRecord::Base # seriously thats it # rails does rest of the magicend
Create the table$ rake db:migrate(in /path/to/myapp)== CreateTodos: migrating ================-- create_table(:todos) -> 0.0015s== CreateTodos: migrated (0.0016s) ===========================================
The Rails consoleThe REPL for Rails
$ rails consoleLoading development environment (Rails 3.0.7)ruby-1.9.2-p180 :001 >
Create a new object
> todo=Todo.new# => #<Todo id: nil, title: nil, done: nil, completed_at: nil, created_at: nil, updated_at: nil>> todo.title="Some title"# => "Some title"> todo.save# AREL (0.5ms) INSERT INTO "todos" ("title", "done", "completed_at", "created_at", "updated_at") VALUES ('Some title', NULL, NULL, '2011-06-25 04:21:47.272312', '2011-06-25 04:21:47.272312') => true
> todo = Todo.new(:title=>"Teach Rails",:done=>true,:completed_at=>Time.now) => #<Todo id: nil, title: "Teach Rails", done: true, completed_at: "2011-06-25 04:26:29", created_at: nil, updated_at: nil>> todo.save AREL (0.8ms) INSERT INTO "todos" ("title", "done", "completed_at", "created_at", "updated_at") VALUES ('Teach Rails', 't', '2011-06-25 04:26:29.853087', '2011-06-25 04:26:38.869335', '2011-06-25 04:26:38.869335') => true
Create a new object
Querying
> Todo.where(:done=>true).all Todo Load (0.4ms) SELECT "todos".* FROM "todos" WHERE "todos"."done" = 't' => [#<Todo id: 2, title: "Teach Rails", done: true, completed_at: "2011-06-25 04:26:29", created_at: "2011-06-25 04:26:38", updated_at: "2011-06-25 04:26:38">]
> t = Todo.where(:done=>true).first Todo Load (0.4ms) SELECT "todos".* FROM "todos" WHERE "todos"."done" = 't' LIMIT 1 => #<Todo id: 2, title: "Teach Rails", done: true, completed_at: "2011-06-25 04:26:29", created_at: "2011-06-25 04:26:38", updated_at: "2011-06-25 04:26:38">> t.done=false => false> t.save AREL (0.5ms) UPDATE "todos" SET "done" = 'f', "updated_at" = '2011-06-25 05:31:07.025845' WHERE "todos"."id" = 2 => true
Update object
Deleting objects
> t.destroy AREL (0.5ms) DELETE FROM "todos" WHERE "todos"."id" = 2 => #<Todo id: 2, title: "Teach Rails", done: false, completed_at: "2011-06-25 04:26:29", created_at: "2011-06-25 04:26:38", updated_at: "2011-06-25 05:31:07">
Relationships$ rails g bucket name:string$ rails g task title:string done:boolean bucket:references
class Bucket < ActiveRecord::Base has_many :tasksend
class Task < ActiveRecord::Base belongs_to :bucketend
create_table :buckets do |t| t.string :name t.timestampsend
create_table :tasks do |t| t.string :title t.boolean :done t.references :bucket t.timestampsend
Creating and querying relationships
> bucket = Bucket.create(:name=>"work") # create work bucket> bucket.tasks.create(:title=>"Fill in timesheets") # create task under bucket> bucket.tasks.create(:title=>"Fix bug #234") #create another task> bucket.tasks.count # => 2> bucket.tasks> t=Task.first # get the task object> t.bucket # access the bucket object from the task object
Still awake?
Controllers & Routes
config/routes.rbMyapp::Application.routes.draw do # direct root (/) to WelcomeController's # index action root :to => "welcome#index"end
$ rails g controller welcome
Welcome Controller# app/controllers/welcome_controller.rbclass WelcomeController < ApplicationController def index render :text=>"hello world" endend
Views# app/controller/welcome_controller.rbclass WelcomeController < ApplicationController def index @time = Time.now endend
<!-- in app/views/welcome/index.html.erb --><h1>The time is <%=@time.strftime('%d-%b-%Y %H:%M:%S')%></h1>
ReST and ResourcesMyapp::Application.routes.draw do resources :tasksend
$ rake routes(in /path/to/myapp) tasks GET /tasks(.:format) {:action=>"index", :controller=>"tasks"} POST /tasks(.:format) {:action=>"create", :controller=>"tasks"} new_task GET /tasks/new(.:format) {:action=>"new", :controller=>"tasks"}edit_task GET /tasks/:id/edit(.:format) {:action=>"edit", :controller=>"tasks"} task GET /tasks/:id(.:format) {:action=>"show", :controller=>"tasks"} PUT /tasks/:id(.:format) {:action=>"update", :controller=>"tasks"} DELETE /tasks/:id(.:format) {:action=>"destroy", :controller=>"tasks"}
class TasksController < ApplicationController # index displays a list of tasks # new presents a form to create a task # create processes the form submitted by the new action # show displays an individual task # edit presents a form to update a task # update processes the form submitted by the edit action # destroy deletes a taskend
ReST and Resources
Nested resourcesMyapp::Application.routes.draw do resources :buckets, :shallow=>true do resources :tasks endend
$ rake routes(in /path/to/myapp) bucket_tasks GET /buckets/:bucket_id/tasks(.:format) {:action=>"index", :controller=>"tasks"} POST /buckets/:bucket_id/tasks(.:format) {:action=>"create", :controller=>"tasks"}new_bucket_task GET /buckets/:bucket_id/tasks/new(.:format) {:action=>"new", :controller=>"tasks"} edit_task GET /tasks/:id/edit(.:format) {:action=>"edit", :controller=>"tasks"} task GET /tasks/:id(.:format) {:action=>"show", :controller=>"tasks"} PUT /tasks/:id(.:format) {:action=>"update", :controller=>"tasks"} DELETE /tasks/:id(.:format) {:action=>"destroy", :controller=>"tasks"} buckets GET /buckets(.:format) {:action=>"index", :controller=>"buckets"} POST /buckets(.:format) {:action=>"create", :controller=>"buckets"} new_bucket GET /buckets/new(.:format) {:action=>"new", :controller=>"buckets"} edit_bucket GET /buckets/:id/edit(.:format) {:action=>"edit", :controller=>"buckets"} bucket GET /buckets/:id(.:format) {:action=>"show", :controller=>"buckets"} PUT /buckets/:id(.:format) {:action=>"update", :controller=>"buckets"} DELETE /buckets/:id(.:format) {:action=>"destroy", :controller=>"buckets"}
* If you squint hard enough, you will be able to read it.
BucketsControllerdef index @buckets = Bucket.allend
def show @bucket=Bucket.find(params[:id])end
def destroy @bucket=Bucket.find(params[:id]) @bucket.destroy redirect_to buckets_pathend
BucketsControllerdef new @bucket = Bucket.newend
def create @bucket = Bucket.new(params[:bucket]) if(@bucket.save) flash[:notice] = "Bucket created" redirect_to @bucket else render :action=>:new endend
BucketsControllerdef edit @bucket = Bucket.find(params[:id])end
def update @bucket=Bucket.find(params[:id]) if(@bucket.update_attributes(params[:bucket])) flash[:notice]="Bucket updated" redirect_to @bucket else render :action=>:edit endend
Tasks Controllerdef new @bucket = Bucket.find(params[:bucket_id]) @task = @bucket.tasks.buildend
def create @bucket = Bucket.find(params[:bucket_id]) # the form should have passed bucket_id # as one of the parameters via # a hidden field @task = Task.new(params[:task]) if(@task.save) flash[:notice]="task created" redirect_to @task else render :action=>:new endend
The other actions remain the same
Fantastic Forms
Formtastic# add these to your# Gemfilegem 'formtastic'gem 'jquery-rails'
$ rails g formtastic:install$ rails g jquery:install
<!-- in app/views/buckets/new.html.erb --><%= semantic_form_for @bucket do |f| %> <%= f.inputs %> <%= f.buttons %><% end %>
Hands On
Vagmi Mudumbaivagmi@dharanasoft.com
twitter.com/vagmifacebook.com/vagmilinkedin.com/in/vagmigithub.com/vagmiplus.google.com/106483555843485143380/
Thank you