Searching RESTful style

Hello list,

Ok, first I would like to say I'm starting to get the hang of thinking the RESTful way. But, one thing that is still perplexing my conditioned brain is how to incorporate searching into the RESTful Rails style.

I'm sure this is a basic question, but I'd really like to see some examples what what people are doing in this regard.

So I understand that I have URLs like:

http://example.com/posts http://example.com/posts/123/comments

But, what is the preferred technique for filtering those resource collections with conditions. I'm fairly sure you wouldn't want to add a custom action like:

map.resource :posts, :collection => { :search => :get }

and add more for each type of search you want to perform.

I'm guessing that you would do something more dynamic inside the standard index action. Somehow I seem to have missed seeing any examples the RESTful way to do this.

Do we do something like:

http://example.com/posts?publish_date_from=2007-05-01&publish_date_to=2007-05-15

And then determine within the index action if a query string exists and have conditions to deal with each different set of possible search criteria. I'm sure there's a cleaner, easier way than that.

Any thoughts would be greatly appreciated, Robert Walker

Personnaly, I would have a 'search' resource. To fetch results, you simply GET from this resource. Back to your example, I would add routes such as:

/search/posts/:publish_date_from/:publich_date_to/

and perform the search query in the show action.

You could extend this resource:

/search/:model/:criteria*

Hope that helps,

Pierre,

Hope that helps,

Yes that does help quite a bit actually. What used to be about as clear as mud, is now about as clear as milk. I feel I'm close to seeing the solution, but still can't quite see past the obstruction (err abstraction).

I'm still a bit of a novice with Rails, so I'm still struggling a bit on how to map out the routes and such. It would help to have a concrete example showing such things as the map.resources, a basic controller action for having a "Search" resource, etc. Could a "Search" resource be used generically to query any ActiveRecord subclasses?

Yes that does help quite a bit actually. What used to be about as clear as mud, is now about as clear as milk. I feel I'm close to seeing the solution, but still can't quite see past the obstruction (err abstraction).

Cool!

I'm still a bit of a novice with Rails, so I'm still struggling a bit on how to map out the routes and such. It would help to have a concrete example showing such things as the map.resources, a basic controller action for having a "Search" resource, etc. Could a "Search" resource be used generically to query any ActiveRecord subclasses?

Sorry, you're right: Show! Don't Tell!

'ruby script/generate scaffold_resource Model' will generated a lot of stuff.

If you need CRUD actions on a model mapped to a 'real' table in your database, don't change anything! Notice the map.resources :model added to your routes.rb. It has generated for you the routes you need. Maybe you just want to tweak your controller, with a:   before_filter :admin_authorize, :only => [:delete,:update]

You'll have all the actions and views you need to CRUD your table. See your app/views/model/*.rhtml for details.

What about the search resource? It's a little more complicated (hey! it's not a big thing! It's Rails, not Struts!)... So we want to have an action mapped to a route like: /search/posts/:publish_date_from/:publish_date_to/

First, 'ruby script/generate scaffold_resource Search' will do for you the half of work. But you still need to tweak the show action:

  def show     @results = Post.find_by_publish_date_from_and_publish_date_to(params[:publish_date_from],params[:publish_date_to])

    respond_to do |format|       format.html #do fancy stuff with @results in your view       format.xml {}     end   end

Remove the DELETE and UPGRADE actions in this example, since you won't need it. The INDEX one will be used to show a form for your customers to enter those informations (params[:publish_date_from],params[:publish_date_to]).

What about the routes? Remove the map.resources :searches since it's not the type of routes you need. Instead, you could do something like:   map.search '/search/posts/:publish_date_from/:publish_date_to',               :controller => 'searches',               :action => 'show',               :conditions => {:method => :get}

The search resource is actually a bad example since you only need a GET. For example, in a auth_admins resource (wich will CRUD cookies for authorizations), /logout is mapped to the destroy action:   def destroy     session[:id] = nil

    respond_to do |format|       format.html { redirect_to auth_admins_url }       format.xml { head :ok }     end   end   map.cabinet_logout 'logout', :controller => 'auth_cabinets', :action => 'destroy', :conditions => {:method => :put}

Be careful to respect the ' and :, since conventions for them in the routes module suck (erf, should I say: I don't understand them?).

Actually, I'm not sure about the pluralization of 'search'. Just add in your config/environment.rb: Inflector.inflections do |inflect|    inflect.irregular 'search', 'searches' end

Hope I'm clear,