form_for helper (use for posting new resources)
http://localhost:3000/projects
form_for is the helper method rails provides for you when you create a new resource using scaffolding:
> rails generate scaffold Project name:string
<%= form_for(@project) do |f| %> <div class="field"> <%= f.label :name %><br /> <%= f.text_field :name %> </div> <div class="actions"> <%= f.submit %> </div> <% end %>
And it produces HTML that looks like this:
<form action="/projects" id="new_project" method="post"> <div class="field"> <label for="project_name">Name</label><br /> <input id="project_name" name="project[name]" type="text" /> </div> <div class="actions"> <input name="commit" type="submit" value="Create Project" /> </div> </form>
It knows where to route this request because scaffolding adds ‘projects’ to the routes table:
routes.rb Foo::Application.routes.draw do resources :projects
But before it will render we need to setup the @project variable in our controller (which scaffolding thankfully does for us):
class ProjectsController < ApplicationController def new @project = Project.new end end
That in a nutshell is mechanics behind form_for.
form_tag (use for generic posts i.e. search)
form_tag is different. With form_tag we aren’t updating a resource. We just want to create a form and send something to the backend via a post (i.e. we want to do a search).
<h1>Listing projects</h1> <%= form_tag projects_path do %> <p> <%= text_field_tag :search %> <%= submit_tag "Search" %> </p> <% end %>
This renders:
<h1>Listing projects</h1> <form action="/projects" method="post"> <p> <input id="search" name="search" type="text" /> <input name="commit" type="submit" value="Search" /> </p> </form>
Now by default if we just left this like this and tested out our new search it wouldn’t work.
Instead of doing a search for us (which we haven’t defined yet) it would try to create a new project because of the ‘post’ method in the form action.
So what we need to do is turn this into a ‘get’.
<%= form_tag projects_path, :method => 'get' do %>
And then implement some search:
class ProjectsController < ApplicationController def index if params[:search] @projects = Project.find(:all, :conditions => ['name LIKE ?', "%#{params[:search]}%"]) else @projects = Project.all end end
Note: the URL for our search is:
http://localhost:3000/projects?search=foo&commit=Search
Thanks to Ryan Bates for his rails cast (of which this post is based)
http://railscasts.com/episodes/37-simple-search-form
And Michael Hartl’s excellent:
http://ruby.railstutorial.org/chapters/sign-up#sec:using_form_for
jiji
Sep 16, 2011 @ 11:43:50
is it better to use form_tag for a multiple delete?
JR
Sep 17, 2011 @ 19:31:40
Good question jiji I don’t know. I haven’t tried that yet. Anyone?
jiji
Sep 19, 2011 @ 09:36:57
I finally got a way of doing it, based on Ryan Bates tutorials for multiple update
I had to adapt my controller method so they get my attributes and delete them.
I just went wrong on the restful method and the routes (maybe because I’m still a noob) I used put instead of delete
but now it’s all working 🙂
hope it will help other people
JR
Sep 21, 2011 @ 12:10:43
Good stuff jiji. I am new and learning too, so I know the feeling and rush that comes from connecting the dots and figuring it out. Good stuff!
Thanks for sharing. Best of luck on your project.