0
Rails <form> Chronicle
history of “name” attribute and form_* helper methods.



                    2008 / 2 / 16
      P...
•( )
  • 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])


   •
 ...
What is <form>?
<form> is an          HTML element.
• form
•                      HTTP


 <form id=”new_entry” action=”/entries” method=”P...
<form> is an   Interface.
•
    User Interface.
<form> has some           Controls.
  •               Control       (input or so)

  • Control        name

<form id=”new_...
What is control’s

        “name” attribute.
• name

    •

•
    “name”
“name” attribute is
    the Programming Interface

• form   API !

 •                 name    API !

•         action     ...
<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 tit...
Examples
<form action=”...”>
  <input name=”title” type=”text” />
  <input name=”body” type=”text” />
</form>




{:title ...
Examples
<form action=”...”>
  <input name=”entry[title]” type=”text” />
  <input name=”entry[body]” type=”text” />
</form...
Examples
<form action=quot;...quot;>
  <input type=quot;textquot;   name=quot;entry[title]quot; />
  <input type=quot;text...
Phase 2



From Controller to
  Model (and DB)
Rails handle Hash as
AR constructor argument.
• Rails   Hash ActiveRecord




hash = { :entry => {:title => “new title”,
 ...
And, of course, Rails can
    save AR object to DB
•             Rails   ActiveRecord       DB




entry = Entry.new(hash)...
Therefore Rails can
save form-data to DB at ease.
•        Rails        form
                 DB


entry = Entry.new(param...
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>



• HTM...
Thin wrapper for
        HTML <form> tag.
form_tag(
  {:controller=>”entries”,:action=>”create”},
  {:id=>”new_entry”, :me...
and
there is lovely end_form_tag()

    # Outputs “</form>”
    def end_form_tag
      “</form>”
    end
ActionView::Helpers::
                 FormHelper.
•                           FormHelper            !!

    @entry = Entr...
ActionView::Helpers::
             FormHelper.
@entry = Entry.new(:title=>”             ”)
text_field(:entry, :title)

# =...
ActionView::Helpers::
                FormHelper.
    text_field(object, method, options={})


•                          ...
rem
          ind
                Examples
<form action=”...”>
  <input name=”entry[title]” type=”text” />
  <input name=”...
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 specifi...
form for the object.

•
    •   text_field()

    •                 ==


<%# @entry                 %>
<% form_for(:entry,
...
form_for()
            remembers the object.
•
                       ActionView::FormBuilder

• text_field(method, options...
ActionView::
               FormBuilder
<% form_for(:entry,
            :url=>{:action=>”crate”}) do |f| %>
  <label>Title...
FYI: 2nd argument.
•
<% entry_local = Entry.new(:title=>”local”) %>

<% form_for(:entry,
            entry_local,
        ...
OK, but

                 Why form_for()?
rem i
      nd
          • Rails                 Hash

re min
       d
         ...
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.dr...
new form_for()
<% @entry = Entry.find(1) %>

<% form_for(@entry) do |f|%>
  ...
<% end %>

                      generates...
form_for()
     determine the form identity.
<form action=quot;/entries/1quot;   class=quot;edit_entryquot;
     id=quot;e...
new Convention for
             DOM ID & CSS class
<form action=quot;/entries/1quot;   class=quot;edit_entryquot;
     id=...
d
    re min            form_for()
             remembers the object.

•              FormBuilder


         <% form_for(@...
ActionView::
          FormBuilder#label
• label(method,    text=nil, options={})


<% form_for(:entry,
            :url=>...
form_for()
understands the object’s status.
<form action=quot;/entries/1quot; class=quot;edit_entryquot;
  id=quot;edit_en...
bigger

    Convention for CRUD

• HTTP              CRUD     Convention
          RFC2616

• Rails
on RubyKaigi2006,

                  DHH said
 GET              POST                  PUT               DELETE


 find     ...
HTTP methods and actions
GET      /entries/:id
{:controller=>quot;entriesquot;, :action=>quot;showquot;}


PUT      /entri...
HTTP Method                 !
HTTP Method
               !
                          CRUD
ActiveRecord                    ...
class EntriesController < ApplicationController
  def show
    @entry = Entry.find(params[:id])
  end

  def create
    @e...
class EntriesController < ApplicationController
  def show
    @entry = Entry.find(params[:id])
  end

  def create
    @e...
class EntriesController < ApplicationController
    def show
      @entry = Entry.find(params[:id])
    end

       def cr...
class EntriesController < ApplicationController
    def show
      @entry = Entry.find(params[:id])
    end

    def creat...
class EntriesController < ApplicationController
    def show
      @entry = Entry.find(params[:id])
    end

    def creat...
FYI: about PUT and DELETE
•            PUT



 • POST
 • _method
<form action=quot;/entries/1quot; class=quot;edit_entryqu...
rem
           ind    I’ve talked about
features of form_for()w/ Rails 2.0
•                                 form DOM ID
 ...
One more
(sad) thing..
Good bye end_form_tag()




                       iabl e or
               cal var
        ned lo             ag’
  un de...
Conclusion
the Goal
entry =
  Entry.new(params[:entry])

entry.save()
Where         form_for()   and


  AC::Resource          going to?

• Web                    CRUD

 •

• relationship   CR...
Conclusion of
          Conclusions
•Rails 2.0 form_for()

•AC::Resources
•Rails           blog   2.0
                    ...
Any
Question?
FAQ:
     ActiveResource               ?            ?

• RESTful        Web
                                       ARes

•...
FAQ:             +
                         ?

•        Rails 1.2

• DOM ID

•          1.2       URL
FAQ:
        form_for()                     ?

• config/routes.rb     resource

 •map.resources      resource_plural

• new...
FAQ:               ?
               1


• AR::Base.new()
 •                 OK

 •
 •                          :- )
FAQ:                                    ?
                    1
class Entry < ActiveRecord::Base
  has_many :tags

 def ta...
References
• Rails                               (         )

• RESTful Web
 •   http://amazon.jp/o/ASIN/4873113539/morodi...
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;...
2 ways for handling nested resource

     AC::Resources style
• URL
# config/routes.rb

map.resources :blog, :has_many=>:e...
2 ways for handling nested resource

     AC::Resources style
•
# http://exapmle.com/entries
@entries = Entry.entries.find...
form_for()         and REST
• HTTP is next TCP/IP
 •       TCP

 •             HTTP

• Man Machine Interface
 •
 •        ...
Man Machine Interface
         and REST
•                    Human Interface

 • iPhone      NintendoDS

 •            Mac...
Rails <form> Chronicle
Rails <form> Chronicle
Rails <form> Chronicle
Rails <form> Chronicle
Upcoming SlideShare
Loading in...5
×

Rails <form> Chronicle

7,237

Published on

form_forすごい。超すごい

Published in: Technology
0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
7,237
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
35
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

Transcript of "Rails <form> Chronicle"

  1. 1. Rails <form> Chronicle history of “name” attribute and form_* helper methods. 2008 / 2 / 16 PostgreSQL / Ruby / Rails @
  2. 2. •( ) • Ruby Rails • Rails @ •
  3. 3. Acknowledgments • • PostgreSQL / Ruby • • •Rails @ •
  4. 4. Acknowledgments
  5. 5. • ( ) Rails • Rails • Ruby
  6. 6. Contact me •k-morohashi@esm.co.jp (work) •moronatural@gmail.com (private) •http://d.hatena.ne.jp/moro/ • :- )
  7. 7. • blog FeedList http://feedlist.net/
  8. 8. Conclusion • / # in app/controllers/entries_controller.rb entry = Entry.new(params[:entry]) • •form
  9. 9. What is <form>?
  10. 10. <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>
  11. 11. <form> is an Interface. • User Interface.
  12. 12. <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>
  13. 13. What is control’s “name” attribute. • name • • “name”
  14. 14. “name” attribute is the Programming Interface • form API ! • name API ! • action method
  15. 15. <form> is an Interface. • User Interface • Programing Interface
  16. 16. How does Rails handle?
  17. 17. Phase 1 From View to Controller
  18. 18. 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”}}
  19. 19. Examples <form action=”...”> <input name=”title” type=”text” /> <input name=”body” type=”text” /> </form> {:title => “new title”, :body => ”new body”}
  20. 20. Examples <form action=”...”> <input name=”entry[title]” type=”text” /> <input name=”entry[body]” type=”text” /> </form> { :entry => {:title => “new title”, :body => ”new body” }}
  21. 21. 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;]}}
  22. 22. Phase 2 From Controller to Model (and DB)
  23. 23. 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”
  24. 24. And, of course, Rails can save AR object to DB • Rails ActiveRecord DB entry = Entry.new(hash) entry.title # => “new title” entry.save
  25. 25. Therefore Rails can save form-data to DB at ease. • Rails form DB entry = Entry.new(params[:entry]) entry.save
  26. 26. In other words, entry = Entry.new(params[:entry]) • params[ ] • form name
  27. 27. Rails <form> Chronicle history of “name” attribute and form_* helper methods.
  28. 28. ~ Rails 1.0 Before form_for()
  29. 29. form_tag(url_for_options = {}, options = {}, *parameters_for_url) • Rails 1.0 <form> • HTML form • action url_for_options • options
  30. 30. 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”>
  31. 31. and there is lovely end_form_tag() # Outputs “</form>” def end_form_tag “</form>” end
  32. 32. ActionView::Helpers:: FormHelper. • FormHelper !! @entry = Entry.new(:title=>” ”) text_field(:entry, :title) # => <input type=”text” name=”entry[title]” value=” ” /> • ActiveRecord (=DB ) form
  33. 33. ActionView::Helpers:: FormHelper. @entry = Entry.new(:title=>” ”) text_field(:entry, :title) # => <input type=”text” name=”entry[title]” value=” ” /> and you will get {:entry => {:title => “ ” }}
  34. 34. ActionView::Helpers:: FormHelper. text_field(object, method, options={}) • object ”@#{object}” • method • “#{object}[#{name}]” name input
  35. 35. 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” }}
  36. 36. Rails 1.1& Rails1.2 form_for() has come.
  37. 37. form_for( object_name, *args, &proc) • Rails 1.1 • • URL • • “Creates a form and a scope around a specific model object, ”(from API Document)
  38. 38. form for the object. • • text_field() • == <%# @entry %> <% form_for(:entry, :url=>{:action=>”crate”}) do |f| %> ... <% end %>
  39. 39. 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 %>
  40. 40. 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>
  41. 41. 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
  42. 42. 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 • ↑↑
  43. 43. OK, but Does it works well? • has_many :through • CRUD • RDBMS
  44. 44. But... • form_for (Rails @ ) • • end_form_tag() obsolete • (?) •
  45. 45. Rails 2.0 form_for() meets Resource
  46. 46. form_for() and map.resource • AR ”resource” •“resource” HTTP CRUD ActionController::Routes.draw do |m| map.resources :entries end
  47. 47. 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>
  48. 48. 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
  49. 49. 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()
  50. 50. d re min form_for() remembers the object. • FormBuilder <% form_for(@entry) do |f| %> <label>Title</label> <%= f.text_field :title %> <% end %>
  51. 51. 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> ...
  52. 52. 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
  53. 53. bigger Convention for CRUD • HTTP CRUD Convention RFC2616 • Rails
  54. 54. on RubyKaigi2006, DHH said GET POST PUT DELETE find create update destroy SELECT INSERT UPDATE DELETE http://media.rubyonrails.org/presentations/worldofresources.pdf
  55. 55. 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;}
  56. 56. HTTP Method ! HTTP Method ! CRUD ActiveRecord ! ActiveRecord DB CRUD !! DB CRUD form_for resource oriented form .... HTTP CRUD
  57. 57. 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
  58. 58. 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
  59. 59. 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
  60. 60. 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
  61. 61. 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
  62. 62. 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>
  63. 63. rem ind I’ve talked about features of form_for()w/ Rails 2.0 • form DOM ID CSS • FormBuilder •
  64. 64. One more (sad) thing..
  65. 65. Good bye end_form_tag() iabl e or cal var ned lo ag’ un defi _for m_t od `end meth
  66. 66. Conclusion
  67. 67. the Goal entry = Entry.new(params[:entry]) entry.save()
  68. 68. Where form_for() and AC::Resource going to? • Web CRUD • • relationship CRUD • has_many :through
  69. 69. Conclusion of Conclusions •Rails 2.0 form_for() •AC::Resources •Rails blog 2.0 !! • &
  70. 70. Any Question?
  71. 71. FAQ: ActiveResource ? ? • RESTful Web ARes • Rails ActionController ARes • ActionController::Resouces •
  72. 72. FAQ: + ? • Rails 1.2 • DOM ID • 1.2 URL
  73. 73. FAQ: form_for() ? • config/routes.rb resource •map.resources resource_plural • new_record? id • AR • aggregate •↑ Array Hash
  74. 74. FAQ: ? 1 • AR::Base.new() • OK • • :- )
  75. 75. 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
  76. 76. 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
  77. 77. Epilogue
  78. 78. REST and Rails • HTTP CRUD • form_for() HTML UI
  79. 79. handling nested resouce • CRUD • (id=2) (id=5) • (id=2)
  80. 80. 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>
  81. 81. 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”>
  82. 82. 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)
  83. 83. form_for() and REST • HTTP is next TCP/IP • TCP • HTTP • Man Machine Interface • • Web REST
  84. 84. Man Machine Interface and REST • Human Interface • iPhone NintendoDS • Mac Windows • Web REST • Rails 2.0
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×