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

Like this? Share it with your network

Share

Rails <form> Chronicle

  • 9,348 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
9,348
On Slideshare
9,162
From Embeds
186
Number of Embeds
4

Actions

Shares
Downloads
35
Comments
0
Likes
4

Embeds 186

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

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