RestFul Rails Dev v 0 1

download RestFul Rails Dev v 0 1

of 47

Transcript of RestFul Rails Dev v 0 1

  • 8/14/2019 RestFul Rails Dev v 0 1

    1/47

    Rails RESTRESTful Rails Development

    [email protected]

    Http get post

    get post,

    get post http

    http put delete

    WEB

    http put

    delete REST http get, post,put, delete Rails 1.2 REST

    REST

    REST Rails

    scaffolding controller model

    RESTREST

    REST

    -

    REST RESTAJAX

    RESTActiveResource-- REST

  • 8/14/2019 RestFul Rails Dev v 0 1

    2/47

    Rails

    :)

    1.1 RESTREST Roy Fielding Ph.D.

    Representational State Transfer.

    REST http get, post, put,

    delete

    REST URL http

    HTMLXML

    RSS Rails REST

    url model action, url

  • 8/14/2019 RestFul Rails Dev v 0 1

    3/47

    1.1 URL

    URL

    Rails controller model

    1.1 3"project", 3

    Project model( ActiveRecord) 3

    1.2 REST? MVC Rails 2

    REST?

  • 8/14/2019 RestFul Rails Dev v 0 1

    4/47

    REST Rails

    a) Url. REST URL action. RESTURL controller

    id URL http get, post,

    put, delete

    b) controller,

    action action,

    html, xml, RSS

    REST

    c) action

    (DRY don't repeat yourself), controller

    d) CRUD controller. CRUD

    Create,Retrieve,Update,Delete.

    controller model controllermodel

    e) REST

    1.3

  • 8/14/2019 RestFul Rails Dev v 0 1

    5/47

    REST

    ~ REST MVC REST

    a) controller respond_to b) link form helper

    c) controller redirect url

    d) routes.rb

    REST , REST

    1.4 RapidWeb Development mit Ruby on

    Rails Rails REST

    REST

    rails

    > rails ontrack

    > mysql -u rails -p

    Enter password: *****

    mysql> create database ontrack_development;

    mysql> create database ontrack_test;

    mysql> quit

  • 8/14/2019 RestFul Rails Dev v 0 1

    6/47

    1.4.1 Rails 1.2

    rails 1.2

    rails 1.2

    rails 1.2rails 1.2 tag rel _1-2-1 rake

    ontrack 1.2

    > cd ontrack

    > rake rails:freeze:edge TAG=rel_1-2-1

    1.5 Resource Scaffolding

    REST rails (scaffold)

    scaffold_resource

    project, model

    migration,

    > cd ontrack

    > ruby script/generate scaffold_resource project name:string desc:text

    exists app/models/

    exists app/controllers/

    exists app/helpers/

    create app/views/projects

    exists test/functional/

    exists test/unit/

    create app/views/projects/index.rhtml

  • 8/14/2019 RestFul Rails Dev v 0 1

    7/47

    create app/views/projects/show.rhtml

    create app/views/projects/new.rhtml

    create app/views/projects/edit.rhtml

    create app/views/layouts/projects.rhtmlcreate public/stylesheets/scaffold.css

    create app/models/project.rb

    create app/controllers/projects_controller.rb

    create test/functional/projects_controller_test.rb

    create app/helpers/projects_helper.rb

    create test/unit/project_test.rb

    create test/fixtures/projects.yml

    create db/migrate

    create db/migrate/001_create_projects.rb

    route map.resources :projects

    model, controller, view, migration

    routes.rb map.resources :projects controller REST

    routes.rb,

    1.6 Model Rails REST controller

    model model ActiveReocrd

    ActiveRecord::Base

    class Project < ActiveRecord::Baseend

  • 8/14/2019 RestFul Rails Dev v 0 1

    8/47

    model

    > rake db:migrate

    1.7 Controller

    controller ProjectsController CRUD

    controller,Project projects

    controller

    CRUD

    Listing 1.1: ontrack/app/controllers/projects controller.rbclass ProjectsController < ApplicationController

    # GET /projects# GET /projects.xmldef index...# GET /projects/1# GET /projects/1.xmldef show...# GET /projects/newdef new...# GET /projects/1;editdef edit...# POST /projects# POST /projects.xmldef create...

  • 8/14/2019 RestFul Rails Dev v 0 1

    9/47

    # PUT /projects/1# PUT /projects/1.xmldef update...end# DELETE /projects/1# DELETE /projects/1.xmldef destroy...

    end

    ProjectController

    (create)(retrieve)

    (update)(delete) Project

    Controller Action

    Action url http

    REST URL URL

    1.7.1 REST URL

    REST URL Rails

    controller/action/model id /projects/show/1

    REST URL controller id

    /projects/1

    URL action

    /projects/1 URL

    http 4

  • 8/14/2019 RestFul Rails Dev v 0 1

    10/47

    http 4 REST URL

    action:

    POST URL

    URL

    http 4 action

    action URL

    2 URL /projects/1 /projects

    /projects/new , /projects/show/1 , /projects/delete/1,

    /projects/update/1 4 URL.

    POST Get

    http://localhost:3000/projects/1 show

    Action.

    Rails

    Delete (hidden field)

    1.7.2 Action respond_to

  • 8/14/2019 RestFul Rails Dev v 0 1

    11/47

    id URL http

    action URL URL

    Action

    URL REST action

    WEB web

    service xml RSS

    RSS

    scaffold CRUD 4

    show action respond_to

    Listing 1.2: ontrack/app/controllers/projects controller.rb# GET /projects/1# GET /projects/1.xmldef show

    @project = Project.find(params[:id])respond_to do |format|format.html # show.rhtmlformat.xml { render :xml => @project.to_xml }

    endend

    respond_to (block)(block)

    2html xml

    (block) html

    format.html xml format.xml

  • 8/14/2019 RestFul Rails Dev v 0 1

    12/47

    format.html show.rhtml

    respond_to 2 http-header

    URL URL

    1.7.3 http-header accept

    respond_to http-header

    curl webrick

    > ruby script/server webrick

    => Booting WEBrick...

    => Rails application started on http://0.0.0.0:3000

    => Ctrl-C to shutdown server; call with --help for options

    [2006-12-30 18:10:50] INFO WEBrick 1.3.1

    [2006-12-30 18:10:50] INFO ruby 1.8.4 (2005-12-24) [i686-darwin8.6.1]

    [2006-12-30 18:10:50] INFO WEBrick::HTTPServer#start: pid=4709 port=3000

  • 8/14/2019 RestFul Rails Dev v 0 1

    13/47

    curl project xml

    > curl -H "Accept: application/xml" \

    -i -X GET http://localhost:3000/projects/1

    =>

    HTTP/1.1 200 OK

    Connection: close

    Date: Sat, 30 Dec 2006 17:31:50 GMT

    Set-Cookie: _session_id=4545eabd9d1bebde367ecbadf015bcc2; path=/

    Status: 200 OK

    Cache-Control: no-cache

    Server: Mongrel 0.3.13.4

    Content-Type: application/xml; charset=utf-8

    Content-Length: 160

    Future of Online Marketing

    1

    Wunderloop

    Rails show action http-header

    Accept: application/xml xmlshow

    action format.xml xml

  • 8/14/2019 RestFul Rails Dev v 0 1

    14/47

    Curl

    id = 1

    > curl -X DELETE http://localhost:3000/projects/1

    =>

    You are being

    redirected.

    http DELETERails http

    destroy URL http

    1.7.4 URL

    action URL

    id=1 project

    http://localhost:3000/projects/1.xml

    MAC firefox Safari

    Safari xml firefox xml

  • 8/14/2019 RestFul Rails Dev v 0 1

    15/47

    controller URL

    2 controller view REST

    URL

    1.8 REST URL View

    View

    Rails link_to helper

    hashmap, hashmap controller action

    link_to :controller => "projects", :action => "show", :id => project=>Show

    link_to REST

    REST URL action

    http 4 URL

    Rails link_to

    hashmap, path

    controller show action

    controller, action, id

    link_to "Show", project_path(project)=>

  • 8/14/2019 RestFul Rails Dev v 0 1

    16/47

    Show

    path url helper

    Rails

    link_to controller action

    project_path controller id

    REST URLGet

    Rails show action

    rails 7 path 1.2

    path http show,

    create http Get Post

    update,delete

    PUT DELETE

    4 http

    CRUD 2 Get

    new_project_path edit_project_path

  • 8/14/2019 RestFul Rails Dev v 0 1

    17/47

    1.8.1 New Edit

    Get

    controller newaction

    link_to "New", new_project_path=>New

    REST

    new CURD action

    CRUD create form

    id

    id REST URL REST

    URL idnew action

    form

    edit_project_path

    update action update action

    edit_project_path new_project_path

    id REST id controller

    /project/1 Get URL Rails

    show actionedit_project_path

    link_to "Edit", edit_project_path(project)=>Edit

  • 8/14/2019 RestFul Rails Dev v 0 1

    18/47

    edit_project_path new_project_path

    action REST CRUD URL

    URL

    1.8.2 form path Create Update

    form_tag form_for form

    { :action => "create" } do |f|%>...

    REST :url hashmap path

    project_path form

    project_path(:id) form

    a) form

    form post project_path id

    URL/projects

    create action

    form_for(:project, :url => projects_path) do |f| ...=>

  • 8/14/2019 RestFul Rails Dev v 0 1

    19/47

    b) form

    REST http PUT

    Post Get

    form_for :html

    form_for(:project, :url => project_path(@project),:html => { :method => :put }) do |f| ...=>

    Rails http put Rails

    update

    1.8.3

    path

    link_to "Show", project_path(project)link_to "Destroy", project_path(project), :method => :delete

  • 8/14/2019 RestFul Rails Dev v 0 1

    20/47

    :method http

    DELETE DELETERails

    javascript

    link_to "Destroy", project_path(project), :method => :delete=>Destroy

    javascript form http DELETERails destroy

    1.9 Controller URL

    View helper path

    REST URL controller

    redirect controllerurlhelper

    REST URL

    project_url project_path

  • 8/14/2019 RestFul Rails Dev v 0 1

    21/47

    projects_url projects_path

    pathurl URL

    project_url(1)=>

    "http://localhost:3000/projects/1"

    projects_url

    =>

    "http://localhost:3000/projects"

    Rails controllerurl redirect_to

    controller/action

    redirect_to :controller => "projects", :action => "show",:id => @project.id

    REST:

    redirect_to project_url(@project)

    destroy action

    project_url

    controlleraction

    Listing 1.3: ontrack/app/controllers/projects controller.rbdef destroy

    @project = Project.find(params[:id])@project.destroyrespond_to do |format|

    format.html { redirect_to projects_url }format.xml { head :ok }

    end

  • 8/14/2019 RestFul Rails Dev v 0 1

    22/47

    end

    1.10 REST

    RESTform,controller

    helperhelper

    controlleraction

    /config/routes.rb

    map.resources :projects

    scaffold

    controller action

    resources path url helperproject

    map.resources :projects

    =>

    Route Generated Helper

    -----------------------------------------------------------

    projects projects_url, projects_path

    project project_url(id), project_path(id)

    new_project new_project_url, new_project_path

    edit_project edit_project_url(id), edit_project_path(id)

  • 8/14/2019 RestFul Rails Dev v 0 1

    23/47

    1.10.1

    REST REST CRUD link_to html

    link_to "Show", project_path(project)=>Show

    link_to html

    actionRails Get URL show

    actioncontrollershow action

    index, update, delete,create, destroy,new,edit

    REST controller

    1.10.2

    REST

    :controller. controller:path prefix. URL:name prefix. Helper urlpath:singular.

    Sprintsprint

    map.resources :sprints,

  • 8/14/2019 RestFul Rails Dev v 0 1

    24/47

    :controller => "ontrack",

    :path_prefix => "/ontrack/:project_id",

    :name_prefix => "ontrack_"

    URL :path_prefix URL

    /ontrack/+project id controller OntrackController

    URL http://localhost:3000/ontrack/1/sprints

    OntrackControllerindex URL

    http://localhost:3000/ontrack/1/sprints/1

    show

    :path_prefix URL :name_prefix helper

    ontrack_sprints_path(1)=>/ontrack/1/sprintsorontrack_edit_sprint_path(1, 1)=>/ontrack/1/sprints/1;edit

    1.11 REST

    URL URL REST

  • 8/14/2019 RestFul Rails Dev v 0 1

    25/47

    Rails

    model1 ontrack

    projects iterations REST controller

    controller

    Rails RESTRails URL

    URL ontrack

    project iteration

    iteration iterations

    > ruby script/generate scaffold_resource iteration name:string \

    start:date end:date project_id:integer

    > rake db:migrate

    Projects Iterations 1 model:

    Listing 1.4: ontrack/app/models/project.rbclass Project < ActiveRecord::Base

    has_many :iterationsendListing 1.5: ontrack/app/models/iteration.rbclass Iteration < ActiveRecord::Base

    belongs_to :projectend

    model, controller view, config/routes.rb

  • 8/14/2019 RestFul Rails Dev v 0 1

    26/47

    map.resources :iterations

    project iteration project

    new_iteration_path URL /iterations/new

    iteration project

    Rails URL

    map.resources :projects do |projects|projects.resources :iterations

    end

    iteration

    project URL

    /project/:project_id/iterations/project/:project_id/iterations/:id

    URL

    http://localhost:3000/projects/1/iterations

    IterationController index

    :project_id project

    URL

    /projects/1/iterations Project.find(1).iterations

  • 8/14/2019 RestFul Rails Dev v 0 1

    27/47

    URL URLURL

    action 2 REST URL

    show action URL

    http://localhost:3000/projects/1/iterations/1

    1.11.1 controller

    IterationController

    project

    index iterations URL

    project iterations

    Listing 1.6: ontrack/app/controllers/iterations controller.rbdef index

    @iterations = Iteration.find(:all)respond_to do |format|

    format.html # index.rhtmlformat.xml { render :xml => @iterations.to_xml }

    endend

    index project

    iterations

    Listing 1.7: ontrack/app/controllers/iterations controller.rbdef index

    project = Project.find(params[:project_id])

  • 8/14/2019 RestFul Rails Dev v 0 1

    28/47

    @iterations = project.iterations.find(:all)...

    end

    controller

    /projects/:project_id URL index

    create, update

    1.11.2 pathurl helper

    config/routes.rb

    helper helper

    project-iditerations_path

    helper project iterationsHelper

    helper id

    project id

    project

    iterations

    link_to "Iterations", iterations_path(project)

    =>

    Iterations

    iterations_path project

    Listing 1.8: ontrack/app/views/projects/index.rhtml

  • 8/14/2019 RestFul Rails Dev v 0 1

    29/47

    ...

    "Are you sure?", :method => :delete %>...

    iterations_path

    iterations

    Listing 1.9: ontrack/app/views/iterations/index.rhtml...

  • 8/14/2019 RestFul Rails Dev v 0 1

    30/47

    "Are you sure?", :method => :delete %>

    ...

    iteration

    --- /config/routes.rb

    project id, iteration id

    Listing 1.10: ontrack/app/views/projects/index.rhtml...

    20 1 RESTful Rails "Are you sure?",:method => :delete %>

  • 8/14/2019 RestFul Rails Dev v 0 1

    31/47

    ...

    iteration_path(:project_id => iteration.project, :id => iteration)

    1.11.3 Iteration

    ProjectController index.rhtml

    Listing 1.11: ontrack/app/views/projects/index.rhtml...

    "Are you sure?", :method => :delete %>

  • 8/14/2019 RestFul Rails Dev v 0 1

    32/47

    ...

    new_iteration_path helper

    project helper html

    link_to "New Iteration", new_iteration_path(project)

    =>

    New iteration

    IterationController new

    project id ( 1)

    iteration form project id

    Listing 1.12: ontrack/app/views/iterations/new.rhtml iterations_path(params[:project_id])) do |f| %>...=>

    params[:project_id]Rails

    form_for(:iteration, :url => iterations_path)

  • 8/14/2019 RestFul Rails Dev v 0 1

    33/47

    /config/routes.rb

    post/projects/1/iterations

    IterationController create

    IterationController create iteration project

    Listing 1.13: ontrack/app/controllers/iterations controller.rb1 def create2 @iteration = Iteration.new(params[:iteration])3 @iteration.project = Project.find(params[:project_id])45 respond_to do |format|6 if @iteration.save7 flash[:notice] = "Iteration was successfully created."8 format.html { redirect_to iteration_url(@iteration.project,9 @iteration) }10 format.xml { head :created, :location =>11 iteration_url(@iteration.project, @iteration) }12 else13 format.html { render :action => "new" }14 format.xml { render :xml => @iteration.errors.to_xml }15 end16 end17 end

    3project_id8

    11urlhelper

    iteration

    iteration project

  • 8/14/2019 RestFul Rails Dev v 0 1

    34/47

    Listing 1.14: ontrack/app/views/iterations/show.rhtml...

    1.11.4 Iteration

    iteration 21

    form_for iteration project

    id

    form_for(:iteration,

    :url => iteration_path(@iteration),

    :html => { :method => :put }) do |f|

    form_for(:iteration,

    :url => iteration_path(params[:project_id], @iteration),

    :html => { :method => :put }) do |f|

    update

    Listing 1.15: ontrack/app/controllers/iterations controller.rb1 def update2 @iteration = Iteration.find(params[:id])

  • 8/14/2019 RestFul Rails Dev v 0 1

    35/47

    34 respond_to do |format|5 if @iteration.update_attributes(params[:iteration])6 flash[:notice] = "Iteration was successfully updated."7 format.html { redirect_to iteration_url(@iteration) }8 format.xml { head :ok }9 else10 format.html { render :action => "edit" }11 format.xml { render :xml => @iteration.errors.to_xml }12 end13 end14 end

    7

    format.html { redirect_to iteration_url(@iteration.project,@iteration) }

    Iteration

    1.12 Action /config/routes.rb

    CRUD CRUD

    ProjectController close

  • 8/14/2019 RestFul Rails Dev v 0 1

    36/47

    close

    > ruby script/generate migration add_closed_to_projects

    exists db/migrate

    create db/migrate/003_add_closed_to_projects.rb

    Listing 1.16: ontrack/db/migrate/003 add closed to projects.rbclass AddClosedToProjects < ActiveRecord::Migration

    def self.up

    add_column :projects, :closed, :boolean, :default => false

    end

    def self.down

    remove_column :projects, :closed

    end

    end

    rake db:migrate

    IteratinController index.rhtml close

    Listing 1.17: ontrack/app/views/projects/index.rhtml

  • 8/14/2019 RestFul Rails Dev v 0 1

    37/47

    ...2

    1 http

    2 helper

    close CRUDRails

    http close update

    post

    /config/routes.rb

    pathurlhelper

    closeprojects

    memberhashmaphashmap key

    actionhashmapvaluehttp

    map.resources :projects, :member => { :close => :post }

    hashmap value :get, :put, :post, :delete, :any

    :anyhttp

    helper

    :member => { :close => :post }

    postget

  • 8/14/2019 RestFul Rails Dev v 0 1

    38/47

    Rails button_to

    =>

    ProjectController close

    Listing 1.18: ontrack/app/controllers/projects controller.rbdef close

    respond_to do |format|if Project.find(params[:id]).update_attribute(:closed, true)flash[:notice] = "Project was successfully closed."format.html { redirect_to projects_path }format.xml { head :ok }elseflash[:notice] = "Error while closing project."format.html { redirect_to projects_path }format.xml { head 500 }end

    endend

  • 8/14/2019 RestFul Rails Dev v 0 1

    39/47

    :member:collection:new

    :collection

    :collection

    map.resources :projects, :collection => { :rss => :get }--> GET /projects;rss (maps onto the #rss action)

    :member:collection

    :new

    map.resources :projects, :new => { :validate => :post }

    --> POST /projects/new;validate (maps onto the #validate action)

    1.12.1 DRY(Dont Repeat Yourself)

    DRYcontroller

    action /config/routes.rb

    REST

    "close", :id => project %>

    /config/routes.rb

    map.connect :controller/:action/:id

  • 8/14/2019 RestFul Rails Dev v 0 1

    40/47

    1.13

    respond_to

    respond_to do |wants|

    wants.text

    wants.html

    wants.js

    wants.ics

    wants.xml

    wants.rss

    wants.atom

    wants.yaml

    end

    MIME

    PIMvcard

    /config/environment.rb

    Mime::Type.register "application/vcard", :vcard

    show actionvcard

  • 8/14/2019 RestFul Rails Dev v 0 1

    41/47

    def show@address = Address.find(params[:id])respond_to do |format|

    format.vcard { render :xml => @address.to_vcard }...end

    end

    to_vcard ActiveRecord vcard

    RFC2426URL

    http://localhost:3000/addresses/1.vcard

    1.14 REST AJAX

    RESTAJAX

    remote helper

    path helper contoller,

    action

    link_to_remote "Destroy", :url => project_path(project),

    :method => :delete

    =>

    Async Destroy

  • 8/14/2019 RestFul Rails Dev v 0 1

    42/47

    ajax javascript

    ajax

    javascript

    Listing 1.19: ontrack/app/views/layouts/projects.rhtml

    ...

    DestroyProjectsControllerdestroy

    respond_to javascript

    Listing 1.20: ontrack/app/controllers/projects controller.rbdef destroy

    @project = Project.find(params[:id])@project.destroyrespond_to do |format|format.html { redirect_to projects_url }

    format.js # default template destroy.rjsformat.xml { head :ok }

    endend

    format.js

    format.jsRails

    destroy.rjs

    Listing 1.21: ontrack/app/views/projects/destroy.rjs

  • 8/14/2019 RestFul Rails Dev v 0 1

    43/47

    page.remove "project_#{@project.id}"

    rjs project_IDDOM

    project

    Listing 1.22: ontrack/app/views/projects/index.rhtml...

    DRY

    RESTcontrollerjavascript

    REST respond_to

    1.15

    REST

    > rake

    ...

    Started

  • 8/14/2019 RestFul Rails Dev v 0 1

    44/47

    EEEEEEE.......

    IterationsController7

    IterationsControllerscaffold

    iterations

    projects

    project_id

    Listing 1.23: ontrack/test/functional/iterations controller test.rbdef test_should_get_edit

    get :edit, :id => 1, :project_id => projects(:one)assert_response :success

    end

    fixtures

    fixtures :iterations, :projects

    2

    test_should_create_iteration

    test_should_update_iteration

    assert_redirected_to

    iteration_path(assigns(:iteration))

    iteration_path

    project id

  • 8/14/2019 RestFul Rails Dev v 0 1

    45/47

    assert_redirected_to iteration_path(projects(:one), assigns(:iteration))

    redirect path helper RESTREST

    1.16 RESTActiveResource

    ActiveResource RESTActiveResource

    Rails RESTWEBREST

    http 4

    ActiveResource Rails 1.2 svn

    > cd ontrack/vendor

    > mv rails rails-1.2

    > svn co http://dev.rubyonrails.org/svn/rails/trunk rails

    ActiveResource

    ActiveResource::Baseproject

    require "activeresource/lib/active_resource"class Project < ActiveResource::Base

    self.site = "http://localhost:3000"end

  • 8/14/2019 RestFul Rails Dev v 0 1

    46/47

    ActiveResource

    site Project

    ActiveRecord

    project id find wunderloop = Project.find 1

    puts wunderloop.name

    find GET

    GET /projects/1.xml

    xmlxml

    ActiveResource wunderloopActiveRecord

    wunderloop.name = "Wunderloop Connect"

    wunderloop.save

    save put PUT /projects/1.xml

    findsave

    bellybutton = Project.new(:name => "Bellybutton")

    bellybutton.save

    post

    POST /projects.xml

  • 8/14/2019 RestFul Rails Dev v 0 1

    47/47

    bellybutton.destroy

    destroyDELETE

    DELETE /projects/2.xml

    ActiveResource http4REST

    ActiveRecordActiveResource

    Project.find(:all).each do |p|puts p.name

    end

    ActiveResource

    ActiveResource

    1.17

    REST

    RailsREST

    REST