Rails <form> Chronicle

  • 7,126 views
Uploaded on

form_forすごい。超すごい

form_forすごい。超すごい

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
7,126
On Slideshare
0
From Embeds
0
Number of Embeds
1

Actions

Shares
Downloads
35
Comments
0
Likes
4

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Rails <form> Chronicle history of “name” attribute and form_* helper methods. 2008 / 2 / 16 PostgreSQL / Ruby / Rails @
  • 2. •( ) • Ruby Rails • Rails @ •
  • 3. Acknowledgments • • PostgreSQL / Ruby • • •Rails @ •
  • 4. Acknowledgments
  • 5. • ( ) Rails • Rails • Ruby
  • 6. Contact me •k-morohashi@esm.co.jp (work) •moronatural@gmail.com (private) •http://d.hatena.ne.jp/moro/ • :- )
  • 7. • blog FeedList http://feedlist.net/
  • 8. Conclusion • / # in app/controllers/entries_controller.rb entry = Entry.new(params[:entry]) • •form
  • 9. What is <form>?
  • 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. <form> is an Interface. • User Interface.
  • 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. What is control’s “name” attribute. • name • • “name”
  • 14. “name” attribute is the Programming Interface • form API ! • name API ! • action method
  • 15. <form> is an Interface. • User Interface • Programing Interface
  • 16. How does Rails handle?
  • 17. Phase 1 From View to Controller
  • 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. Examples <form action=”...”> <input name=”title” type=”text” /> <input name=”body” type=”text” /> </form> {:title => “new title”, :body => ”new body”}
  • 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. 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. Phase 2 From Controller to Model (and DB)
  • 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. And, of course, Rails can save AR object to DB • Rails ActiveRecord DB entry = Entry.new(hash) entry.title # => “new title” entry.save
  • 25. Therefore Rails can save form-data to DB at ease. • Rails form DB entry = Entry.new(params[:entry]) entry.save
  • 26. In other words, entry = Entry.new(params[:entry]) • params[ ] • form name
  • 27. Rails <form> Chronicle history of “name” attribute and form_* helper methods.
  • 28. ~ Rails 1.0 Before form_for()
  • 29. form_tag(url_for_options = {}, options = {}, *parameters_for_url) • Rails 1.0 <form> • HTML form • action url_for_options • options
  • 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. and there is lovely end_form_tag() # Outputs “</form>” def end_form_tag “</form>” end
  • 32. ActionView::Helpers:: FormHelper. • FormHelper !! @entry = Entry.new(:title=>” ”) text_field(:entry, :title) # => <input type=”text” name=”entry[title]” value=” ” /> • ActiveRecord (=DB ) form
  • 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. ActionView::Helpers:: FormHelper. text_field(object, method, options={}) • object ”@#{object}” • method • “#{object}[#{name}]” name input
  • 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. Rails 1.1& Rails1.2 form_for() has come.
  • 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. form for the object. • • text_field() • == <%# @entry %> <% form_for(:entry, :url=>{:action=>”crate”}) do |f| %> ... <% end %>
  • 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. 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. 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. 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. OK, but Does it works well? • has_many :through • CRUD • RDBMS
  • 44. But... • form_for (Rails @ ) • • end_form_tag() obsolete • (?) •
  • 45. Rails 2.0 form_for() meets Resource
  • 46. form_for() and map.resource • AR ”resource” •“resource” HTTP CRUD ActionController::Routes.draw do |m| map.resources :entries end
  • 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. 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. 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. d re min form_for() remembers the object. • FormBuilder <% form_for(@entry) do |f| %> <label>Title</label> <%= f.text_field :title %> <% end %>
  • 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. 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. bigger Convention for CRUD • HTTP CRUD Convention RFC2616 • Rails
  • 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. 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. HTTP Method ! HTTP Method ! CRUD ActiveRecord ! ActiveRecord DB CRUD !! DB CRUD form_for resource oriented form .... HTTP CRUD
  • 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. 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. 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. 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. 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. 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. rem ind I’ve talked about features of form_for()w/ Rails 2.0 • form DOM ID CSS • FormBuilder •
  • 64. One more (sad) thing..
  • 65. Good bye end_form_tag() iabl e or cal var ned lo ag’ un defi _for m_t od `end meth
  • 66. Conclusion
  • 67. the Goal entry = Entry.new(params[:entry]) entry.save()
  • 68. Where form_for() and AC::Resource going to? • Web CRUD • • relationship CRUD • has_many :through
  • 69. Conclusion of Conclusions •Rails 2.0 form_for() •AC::Resources •Rails blog 2.0 !! • &
  • 70. Any Question?
  • 71. FAQ: ActiveResource ? ? • RESTful Web ARes • Rails ActionController ARes • ActionController::Resouces •
  • 72. FAQ: + ? • Rails 1.2 • DOM ID • 1.2 URL
  • 73. FAQ: form_for() ? • config/routes.rb resource •map.resources resource_plural • new_record? id • AR • aggregate •↑ Array Hash
  • 74. FAQ: ? 1 • AR::Base.new() • OK • • :- )
  • 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. 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. Epilogue
  • 78. REST and Rails • HTTP CRUD • form_for() HTML UI
  • 79. handling nested resouce • CRUD • (id=2) (id=5) • (id=2)
  • 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. 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. 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. form_for() and REST • HTTP is next TCP/IP • TCP • HTTP • Man Machine Interface • • Web REST
  • 84. Man Machine Interface and REST • Human Interface • iPhone NintendoDS • Mac Windows • Web REST • Rails 2.0