shiningthrough

GET and POST in Ruby on Rails

24 May 2007

Lets start with the basics.....

What are GET and POST?

GET and POST specify the two main ways by which the browser sends a form's data to the server for processing.

The Get method contacts the server, and sends the forms data in a single transmission step. The browser appends the data to the forms action URL, separated by the question mark character.

With the POST method, the browser sends the data in two steps. The browser first contacts the server specified in the action attribute, when contact is made the data is sent to the server in a separate transparent transmission.

How does this fit in with Ruby on Rails? a rails form will process its data by default as a POST unless you specify otherwise:

<%= form_tag({:action => 'find_holidays_by_country'}, {:method => 'get'}) %>
<%= end_form_tag %>

Why would you want your form to be a GET? there are many reasons, imagine that a form is used for navigation. After the user has selected their required country, and performed a search, they may want to bookmark the resulting page, this is only possible by use of GET. The following code illustrates this:

<%= form_tag({:action => 'list_holidays_by_country'}, {:method => 'get'}) %>
  <%= select_tag(:country, options_from_collection_for_select(@countries, :name, :name)) %>
    <%= submit_tag 'Search', :name => nil %>
<%= end_form_tag %>

Note that select_tag is used as the helper as it is compatible with a GET request, select, and collection_select are not.
Also note that the name of the country is returned in the URL (more meaningful than an id), as well as being used as the text in the select box. See here for more details.
The submit tag is set to nil, so the button does not show up in the URL.

For a discussion on which method is most appropriate for a given problem, this is a very useful article When To Use GET

Lastly a warning when using GET requests. If an action changes the state of something on the server make sure the request is either a POST, or if GET must be used, make sure some kind of human intervention immediately follows.
Search engine spiders, and web accelerators follow links, and can cause these actions to trigger unintentionally.

Comments

Tim

Can you change the color of your code snipits please, they are hard to read.

shiningthrough

Its been done Tim.

Czar

My question is how to access the checkbox values in controller class from rhtml file The code in rhtml file is like this : <br><p><input type="submit" value="change to aproove"/> <% i = 0 %> <% @hotels.each do |hotel| %> <tr> <td><input type="checkbox" id="<%=hotel.group_name%>_<%=i%>" name="<%=hotel.group_name%>_<%=i%>" value= "<%=i%>" onchange="submit()" >Wanna..Approve?</td> <% i = i + 1 %> <% end %> Please dont worry about @sorttype or anything. Here i am creating a checkbox for each record that is being fetched from database. Now how do i display the name and value of the checkbox "checked" in the controller class. I am trying it for a long time. Please help me. Also i dont know how to use button with that..... Thanks a lot for previous help regards, Czar

Frustrated

This is pretty useless for a newbie. Maybe someone who already knows how to do this may be able to use it. But why would they need you then. Besides, it doesn't even work.

shiningthrough

@Frustrated - this post is aimed at people who want to know more about GET and POST in Rails, its not specifically for beginners or experienced users. In what way did it not work for you? are you referring to the depricated form helpers in Rails 2?

Zobi

Hey shiningthrough, Could you please help me with the following: I have a C++ client and I'm using the cURL library to communicate with a server that runs RoR. From the client I'm sending some GET method and I want my Ruby server to know the type of method sent by the client and deal likewise. So, I want to read the header and know the content has a GET (or whatever) in it. Hope that you can give me the answer I am looking for. Have a nice day and Thanks in advance.

durney insurance

Marcelo, I don't think so.

abc

neat

rajesh

<%= select_tag 'email', "<option>Select</option>".html_safe + options_for_select(@team_member.collect{|x| [x.email]} ) %>