Upload
anon-626529
View
222
Download
0
Embed Size (px)
Citation preview
8/14/2019 RestFul Rails Dev v 0 1
1/47
Rails RESTRESTful Rails Development
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