Search form: POST vs GET

I have a page where members are searched for and added to the group
specified by the url

http://localhost:3000/groups/1/add_members

<%- form_tag :controller => :groups, :action => :add_members do -%>
Find Member by Name: <%= text_field_tag “search_text” %>
<%= submit_tag “Find” %>
<%- end -%>

<%- for member in @members -%> <%- end -%>
<%= link_to "Add to Group", add_member_to_group_url(@group) %> <%= member.full_name %>

The thing that I am having a hard time with is setting up the routes
file since both get and post requests are made for the same page.

To access the page the user clicks on a link
(http://localhost:3000/groups/1/add_members) that takes them to a page
(shown above). The user then searches for a member to add to the group,
which is where the POST occurs.

The controller code (shown below) should then return the members, but it
seems that since the url was accessed through a post, the routing has a
hard time handling it.

def add_members
@group = Group.find(params[:id])
unless params[:search_text].blank?
@members = Member.find_all_by_name(params[:search_text])
else
@members = []
end
end

When the search is attempted I then get the following message returned:

Unknown action
No action responded to 1

which makes sense since the routes.rb file only expects GET requests for
the url:
map.resources :groups, :has_many => :members, :member => {:add_members
=> :get}

and the routes file doesn’t like an additional :add_members => :post (it
was worth a try)

I have made the form submit via a get request, which does make more
sense, and it works. Is this the recommended way to do it? It just
seems that rails is very anti ugly urls, ex:
http://localhost:3000/groups/1/add_members?search_text=&commit=Find

Thanks for the help.

On 12/14/07, Chris O. [email protected] wrote:

The thing that I am having a hard time with is setting up the routes

Unknown action
No action responded to 1

which makes sense since the routes.rb file only expects GET requests for
the url:
map.resources :groups, :has_many => :members, :member => {:add_members
=> :get}

and the routes file doesn’t like an additional :add_members => :post (it
was worth a try)

You seem to be trying to partially use restful design. I think that
the “rails way” would be to use a routing like this:

map.resources :groups do | group |
group.resources :members
end

And then have a restful controller design for the members controller.

Instead of a special add_members action you would use the normal rest
actions

class MembersController < ApplicationController

before_filter :load_group

def load_group
@group = Group.find(params[:group_id])
end

GET /groups/1/members/new

GET /groups/1/members/new.xml

def new
# get a list of members to present to the user to add to the group.
# the actual set of members which can be added is determined by
# business logic in the group model.
# The form rendered by the new action should set params[:id] to the
# id of the member selected. It also needs to set params[:group_id]
to
# the id of the group. The best way to do this is via a hidden
field on the form

@members = @group.potential_new_members

respond_to do |format|
  format.html # new.html.erb
  format.xml  { render :xml => @member }
end

end

POST /groups/1/members

POST /groups/1/members.xml

def create

respond_to do |format|
  # The group model should have a method to add a member, possibly 

with
# some validition. It should return false/nil if the add operation
fails
if @group.add_member(Member.find(params[:id]))
flash[:notice] = ‘Member was successfully created.’
format.html { redirect_to(group_member_path(@group, @member)) }
format.xml { render :xml => @member, :status => :created,
:location => @member }
else
format.html { render :action => “new” }
format.xml { render :xml => @member.errors, :status =>
:unprocessable_entity }
end
end
end
end

The url to prompt for a new member to be added to group 1 would be

/groups/1/members/new

If you really wanted to allow /groups/1/addmembers you could add an
additional route.


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/