• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Rails <form> Chronicle
 

Rails <form> Chronicle

on

  • 9,092 views

form_forすごい。超すごい

form_forすごい。超すごい

Statistics

Views

Total Views
9,092
Views on SlideShare
8,906
Embed Views
186

Actions

Likes
4
Downloads
34
Comments
0

4 Embeds 186

http://d.hatena.ne.jp 147
http://coderwall.com 34
http://www.slideshare.net 4
http://webcache.googleusercontent.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Rails <form> Chronicle Rails <form> Chronicle Presentation Transcript

    • Rails <form> Chronicle history of “name” attribute and form_* helper methods. 2008 / 2 / 16 PostgreSQL / Ruby / Rails @
    • •( ) • Ruby Rails • Rails @ •
    • Acknowledgments • • PostgreSQL / Ruby • • •Rails @ •
    • Acknowledgments
    • • ( ) Rails • Rails • Ruby
    • Contact me •k-morohashi@esm.co.jp (work) •moronatural@gmail.com (private) •http://d.hatena.ne.jp/moro/ • :- )
    • • blog FeedList http://feedlist.net/
    • Conclusion • / # in app/controllers/entries_controller.rb entry = Entry.new(params[:entry]) • •form
    • What is <form>?
    • <form> is an HTML element. • form • HTTP <form id=”new_entry” action=”/entries” method=”POST”> <label for=”entry_title”>Title</label> <input type=”text” id=”entry_title” name=”entry[title]” /> <label for=”entry_body”>Body</label> <textarea id=”entry_body” name=”entry[body]”></textarea> </form>
    • <form> is an Interface. • User Interface.
    • <form> has some Controls. • Control (input or so) • Control name <form id=”new_entry” action=”/entries” method=”POST”> <label for=”entry_title”>Title</label> <input type=”text” id=”entry_title” name=”entry[title]” /> <label for=”entry_body”>Body</label> <textarea id=”entry_body” name=”entry[body]”> </textarea> </form>
    • What is control’s “name” attribute. • name • • “name”
    • “name” attribute is the Programming Interface • form API ! • name API ! • action method
    • <form> is an Interface. • User Interface • Programing Interface
    • How does Rails handle?
    • Phase 1 From View to Controller
    • Rails handle query parameters like a Hash •Rails Hash POST /entry entry[title]=new title&entry[body]=new body params() # =>{ :entry => {:title => “new title”, :body => ”new body”}}
    • Examples <form action=”...”> <input name=”title” type=”text” /> <input name=”body” type=”text” /> </form> {:title => “new title”, :body => ”new body”}
    • Examples <form action=”...”> <input name=”entry[title]” type=”text” /> <input name=”entry[body]” type=”text” /> </form> { :entry => {:title => “new title”, :body => ”new body” }}
    • Examples <form action=quot;...quot;> <input type=quot;textquot; name=quot;entry[title]quot; /> <input type=quot;textquot; name=quot;entry[links][]quot; /> <input type=quot;textquot; name=quot;entry[links][]quot; /> <input type=quot;textquot; name=quot;entry[links][]quot; /> </form> {quot;entryquot;=>{quot;titlequot;=>quot;aaaquot;, quot;linksquot;=>[quot;xxxquot;, quot;yyyquot;, quot;zzzquot;]}}
    • Phase 2 From Controller to Model (and DB)
    • Rails handle Hash as AR constructor argument. • Rails Hash ActiveRecord hash = { :entry => {:title => “new title”, :body => ”new body”}} entry = Entry.new(hash[:entry]) entry.title # => “new title”
    • And, of course, Rails can save AR object to DB • Rails ActiveRecord DB entry = Entry.new(hash) entry.title # => “new title” entry.save
    • Therefore Rails can save form-data to DB at ease. • Rails form DB entry = Entry.new(params[:entry]) entry.save
    • In other words, entry = Entry.new(params[:entry]) • params[ ] • form name
    • Rails <form> Chronicle history of “name” attribute and form_* helper methods.
    • ~ Rails 1.0 Before form_for()
    • form_tag(url_for_options = {}, options = {}, *parameters_for_url) • Rails 1.0 <form> • HTML form • action url_for_options • options
    • Thin wrapper for HTML <form> tag. form_tag( {:controller=>”entries”,:action=>”create”}, {:id=>”new_entry”, :method=>”post”} ) generates <form id=”new_entry” method=”POST” action=>”entries/create”>
    • and there is lovely end_form_tag() # Outputs “</form>” def end_form_tag “</form>” end
    • ActionView::Helpers:: FormHelper. • FormHelper !! @entry = Entry.new(:title=>” ”) text_field(:entry, :title) # => <input type=”text” name=”entry[title]” value=” ” /> • ActiveRecord (=DB ) form
    • ActionView::Helpers:: FormHelper. @entry = Entry.new(:title=>” ”) text_field(:entry, :title) # => <input type=”text” name=”entry[title]” value=” ” /> and you will get {:entry => {:title => “ ” }}
    • ActionView::Helpers:: FormHelper. text_field(object, method, options={}) • object ”@#{object}” • method • “#{object}[#{name}]” name input
    • rem ind Examples <form action=”...”> <input name=”entry[title]” type=”text” /> <input name=”entry[body]” type=”text” /> </form> { :entry => {:title => “new title”, :body => ”new body” }}
    • Rails 1.1& Rails1.2 form_for() has come.
    • form_for( object_name, *args, &proc) • Rails 1.1 • • URL • • “Creates a form and a scope around a specific model object, ”(from API Document)
    • form for the object. • • text_field() • == <%# @entry %> <% form_for(:entry, :url=>{:action=>”crate”}) do |f| %> ... <% end %>
    • form_for() remembers the object. • ActionView::FormBuilder • text_field(method, options={}) • cf : text_field(object, method, options={}) in Rails 1.0 <% form_for(:entry, :url=>{:action=>”crate”}) do |f| %> # @entry#title text field <label>Title</label> <%= f.text_field :title %> <% end %>
    • ActionView:: FormBuilder <% form_for(:entry, :url=>{:action=>”crate”}) do |f| %> <label>Title</label> <%= f.text_field :title %> <% end %> generates <form action=quot;/entries/createquot; method=quot;postquot;> <label>Title</label> <input id=quot;entry_titlequot; name=quot;entry[title]quot; size=quot;30quot; type=quot;textquot; /> </form>
    • FYI: 2nd argument. • <% entry_local = Entry.new(:title=>”local”) %> <% form_for(:entry, entry_local, :url=>{:action=>”crate”}) do |f| %> <label>Title</label> <%= f.text_field :title %> <% end %> • respond_to?(:title) OK
    • OK, but Why form_for()? rem i nd • Rails Hash re min d • “Creates a form and a scope around a specific model object, ” • CRUD HTML • ↑↑
    • OK, but Does it works well? • has_many :through • CRUD • RDBMS
    • But... • form_for (Rails @ ) • • end_form_tag() obsolete • (?) •
    • Rails 2.0 form_for() meets Resource
    • form_for() and map.resource • AR ”resource” •“resource” HTTP CRUD ActionController::Routes.draw do |m| map.resources :entries end
    • new form_for() <% @entry = Entry.find(1) %> <% form_for(@entry) do |f|%> ... <% end %> generates <form action=quot;/entries/1quot; class=quot;edit_entryquot; id=quot;edit_entry_1quot; method=quot;postquot;> <input name=quot;_methodquot; type=quot;hiddenquot; value=quot;putquot; /> ... </form>
    • form_for() determine the form identity. <form action=quot;/entries/1quot; class=quot;edit_entryquot; id=quot;edit_entry_1quot; method=quot;postquot;> <input name=quot;_methodquot; type=quot;hiddenquot; value=quot;putquot; /> ... </form> • ActiveRecord Convention • class ID
    • new Convention for DOM ID & CSS class <form action=quot;/entries/1quot; class=quot;edit_entryquot; id=quot;edit_entry_1quot; method=quot;postquot;> • CSS class ” AR ” • ID ” AR _ DB ID ” • prefix ”edit” ”new” • class ID dom_class() dom_id()
    • d re min form_for() remembers the object. • FormBuilder <% form_for(@entry) do |f| %> <label>Title</label> <%= f.text_field :title %> <% end %>
    • ActionView:: FormBuilder#label • label(method, text=nil, options={}) <% form_for(:entry, :url=>{:action=>”crate”}) do |f| %> <%= f.label :title, “ ” %> <%= f.text_field :title %> <% end %> ... <label for=”entry_title”> <label> ...
    • form_for() understands the object’s status. <form action=quot;/entries/1quot; class=quot;edit_entryquot; id=quot;edit_entry_1quot; method=quot;postquot;> <input name=quot;_methodquot; type=quot;hiddenquot; value=quot;putquot; /> ... </form> • AR • POST /entries PUT /entries/:id
    • bigger Convention for CRUD • HTTP CRUD Convention RFC2616 • Rails
    • on RubyKaigi2006, DHH said GET POST PUT DELETE find create update destroy SELECT INSERT UPDATE DELETE http://media.rubyonrails.org/presentations/worldofresources.pdf
    • HTTP methods and actions GET /entries/:id {:controller=>quot;entriesquot;, :action=>quot;showquot;} PUT /entries/:id {:controller=>quot;entriesquot;, :action=>quot;updatequot;} DELETE /entries/:id {:controller=>quot;entriesquot;, :action=>quot;destroyquot;} POST /entries {:controller=>quot;entriesquot;, :action=>quot;createquot;}
    • HTTP Method ! HTTP Method ! CRUD ActiveRecord ! ActiveRecord DB CRUD !! DB CRUD form_for resource oriented form .... HTTP CRUD
    • class EntriesController < ApplicationController def show @entry = Entry.find(params[:id]) end def create @entry = Entry.new(params[:entry]) @entry.save end def update @entry = Entry.find(params[:id]) @entry.update_attributes(params[:entry]) end def destroy @entry = Entry.find(params[:id]) @entry.destroy end end
    • class EntriesController < ApplicationController def show @entry = Entry.find(params[:id]) end def create @entry = Entry.new(params[:entry]) @entry.save def show end @entry = Entry.find(params[:id]) def update end @entry = Entry.find(params[:id]) @entry.update_attributes(params[:entry]) end def destroy @entry = Entry.find(params[:id]) @entry.destroy end end
    • class EntriesController < ApplicationController def show @entry = Entry.find(params[:id]) end def create @entry = Entry.new(params[:entry]) @entry.save def create end @entry = Entry.new(params[:entry]) @entry.save def update @entry = Entry.find(params[:id]) end @entry.update_attributes(params[:entry]) end def destroy @entry = Entry.find(params[:id]) @entry.destroy end end
    • class EntriesController < ApplicationController def show @entry = Entry.find(params[:id]) end def create @entry = Entry.new(params[:entry]) @entry.save def update end @entry = Entry.find(params[:id]) @entry.update_attributes(params[:entry]) def update @entry = Entry.find(params[:id]) end @entry.update_attributes(params[:entry]) end def destroy @entry = Entry.find(params[:id]) @entry.destroy end end
    • class EntriesController < ApplicationController def show @entry = Entry.find(params[:id]) end def create @entry = Entry.new(params[:entry]) @entry.save def destroy end @entry = Entry.find(params[:id]) @entry.destroy def update @entry = Entry.find(params[:id]) end @entry.update_attributes(params[:entry]) end def destroy @entry = Entry.find(params[:id]) @entry.destroy end end
    • FYI: about PUT and DELETE • PUT • POST • _method <form action=quot;/entries/1quot; class=quot;edit_entryquot; id=quot;edit_entry_1quot; method=quot;postquot;> <input name=quot;_methodquot; type=quot;hiddenquot; value=quot;putquot; /> ... </form>
    • rem ind I’ve talked about features of form_for()w/ Rails 2.0 • form DOM ID CSS • FormBuilder •
    • One more (sad) thing..
    • Good bye end_form_tag() iabl e or cal var ned lo ag’ un defi _for m_t od `end meth
    • Conclusion
    • the Goal entry = Entry.new(params[:entry]) entry.save()
    • Where form_for() and AC::Resource going to? • Web CRUD • • relationship CRUD • has_many :through
    • Conclusion of Conclusions •Rails 2.0 form_for() •AC::Resources •Rails blog 2.0 !! • &
    • Any Question?
    • FAQ: ActiveResource ? ? • RESTful Web ARes • Rails ActionController ARes • ActionController::Resouces •
    • FAQ: + ? • Rails 1.2 • DOM ID • 1.2 URL
    • FAQ: form_for() ? • config/routes.rb resource •map.resources resource_plural • new_record? id • AR • aggregate •↑ Array Hash
    • FAQ: ? 1 • AR::Base.new() • OK • • :- )
    • FAQ: ? 1 class Entry < ActiveRecord::Base has_many :tags def tags_string=(str) str.split(“,”).each{ ... } end def tags_string ts = self.tags ts.map(&:name).join(“, “) entry[tags_string] end end
    • References • Rails ( ) • RESTful Web • http://amazon.jp/o/ASIN/4873113539/morodiary05-22 • Discover of World of resource. • http://media.rubyonrails.org/presentations/worldofresources.pdf • RFC2616( ) • http://www.studyinghttp.net/cgi-bin/rfc.cgi?2616 • HTML 4.01 Specification(ja) • http://www.asahi-net.or.jp/%7Esd5a-ucd/rec-html401j/cover.html
    • Epilogue
    • REST and Rails • HTTP CRUD • form_for() HTML UI
    • handling nested resouce • CRUD • (id=2) (id=5) • (id=2)
    • 2 ways for handling nested resource Ordinary style • blog_id <form action=quot;/entriesquot; class=quot;new_entryquot; id=quot;new_entryquot; method=quot;postquot;> <input type=”hidden” name=”blog_id” value=”2” /> <input type=”text” name=”entry[title]” /> ... </form>
    • 2 ways for handling nested resource AC::Resources style • URL # config/routes.rb map.resources :blog, :has_many=>:entries # in app/views/entries/*.html.erb form_for(@entry,:url=>blog_entries_path(@entry.blog) ) # in HTML <form action=”/blogs/1/entries” method=”POST”>
    • 2 ways for handling nested resource AC::Resources style • # http://exapmle.com/entries @entries = Entry.entries.find(:all) # http://exapmle.com/users/1/entries @user = User.find(params[:user_id]) @entries = @user.entries.find(:all) # http://exapmle.com/blogs/1/entries @blog = Blog.find(params[:blog_id]) @entries = @blog.entries.find(:all)
    • form_for() and REST • HTTP is next TCP/IP • TCP • HTTP • Man Machine Interface • • Web REST
    • Man Machine Interface and REST • Human Interface • iPhone NintendoDS • Mac Windows • Web REST • Rails 2.0