Asking another way - no rest actions in a restful controller

My previous post seems to dead , aka, no replies. Thought I’d take a broader approach. I have a restful controller (created via the scaffold_resources in edgerails). I want to create a search function. While I added the search function into the controller, things seem to by pass my ‘def search…’. Is this normal for a rest controller and can anyone suggest a better way ?

TIA Stuart

My first questions are, "what is the functionality you're trying to create?" and, "do you need a search(es) controller?"

I'm building an app right now that is a search-type tool. I have three different kinds of resources I use: Query (base class), Search and AdvancedSearch (both inherit from Query). So then I've mapped the resources in routes.rb.

Likely, you're not creating models for your searches as I have, but I wouldn't be surprised if creating a "search" or "searches" controller would lead you down the easy path--then you just use the CRUD actions for your searches.

Jamie

My first questions are, “what is the functionality you’re trying to create?” and, “do you need a search(es) controller?”

I’m building an app right now that is a search-type tool. I have three

different kinds of resources I use: Query (base class), Search and AdvancedSearch (both inherit from Query). So then I’ve mapped the resources in routes.rb.

Can you give me some more details on this . Particularly, how you mapped them ?

Likely, you’re not creating models for your searches as I have, but I wouldn’t be surprised if creating a “search” or “searches” controller

would lead you down the easy path–then you just use the CRUD actions for your searches.

Not sure what you mean creating models for searches ? I’ve done all the relationships / associations. What would creating models specific buy me and what does that entail ? I think you might be right about creating a search controller. I was hoping to keep everything contained for the table to search all in one controller. Mentally I’m stuck on the idea that search should be restful, but due to my inexperience I’m not sure I really know why :slight_smile:

Stuart

Here are my routes:

map.resources :queries do |queries|   queries.resources :terms, :member => { :toggle_op => :any } end map.resources :queries, :member => { :add_term => :any }, :collection => { :clear_session => :delete } map.resources :saved_items, :controller => :saved map.resources :searches, :advanced_searches, :documents

Notice you can specify the controller name for a resource. When I started this app, I modeled a Search, but not to the database. Later, I decided we would be using the db and migrated the architecture to use ActiveRecord models. (I'm using Single Table Inheritance with Query as the base class. Queries have Terms.)

Anyway, the main thing about Restful routing of resources is that you now thing of using Resources instead of creating actions. What's a resource? In your case, a Search is a resource, whether it's an ActiveRecord model, some other model, or just a virtual one. What can you do with a resource? You can Create, Update, Delete, and List (index) the. New and Edit are just views that allow you to then Create or Update. Everything that's not the basic CRUD becomes an exception, so I have :toggle_op and :add_term (which arguably, could be Create on Term instead, but actually doesn't work that way in my app).

One thing I've learned about Rails--if you follow the conventions, programming is a lot more rapid and fun. Once you start fighting Rails' opinions, you have to work a lot harder. In this case, view your searches and results as resources. Now you do you architect that with Restful Routes?

http://david.goodlad.ca/articles/2006/08/02/simply_restful-in-rails-core http://microformats.org/wiki/rest/rails

Hope this helps.

Jamie

Jamie, Thank you. Not sure what your asking me "Now you do you architect that

with Restful Routes?" but yes, I think I almost understand about setting things up as resources. The area that still confuses me, and I posted last week about this - map.resources :articles, :collection => {:recent => :get}. I understand that “recent” is the action, via the get method. What I still don’t get is how do you set up the :recent ?

Stuart

typo... "How do you..."

Regarding :recent...

Have a look at the docs for rails edge (you can generate them yourself). Here's an excerpt about custom actions:

Examples:

  map.resources :messages, :path_prefix => "/thread/:thread_id"   # --> GET /thread/7/messages/1

  map.resources :messages, :collection => { :rss => :get }   # --> GET /messages;rss (maps to the #rss action)   # also adds a named route called "rss_messages"

  map.resources :messages, :member => { :mark => :post }   # --> POST /messages/1;mark (maps to the #mark action)   # also adds a named route called "mark_message"

  map.resources :messages, :new => { :preview => :post }   # --> POST /messages/new;preview (maps to the #preview action)   # also adds a named route called "preview_new_message"

  map.resources :messages, :new => { :new => :any, :preview => :post }   # --> POST /messages/new;preview (maps to the #preview action)   # also adds a named route called "preview_new_message"   # --> /messages/new can be invoked via any request method

  map.resources :messages, :controller => "categories",         :path_prefix => "/category/:category_id",         :name_prefix => "category_"   # --> GET /categories/7/messages/1   # has named route "category_message"

I’m sort of seeing but having a hard time envisioning what an advanced search would look like to the user. I can see creating various conditions within my CRUD to call on, by user, by date, by title, etc. At the same time how does one deal with boolean logic in text searches ? I know I’m close but could use a little more explanation, not the code part but the methodology.

Stuart

Okay I appreciate the explanation and yes, probably a bit ahead of myself here. So if you don’t mind I want to run this by you and see if Im on the right start.

I’ve created a search controller but am looking to use my Position model with it.

So without posting the entire controller here , I’ll show the start with index:

class SearchesController < ApplicationController

GET /searches

GET /searches.xml

def index @positions = Position.find(:all)

respond_to do |format|
  format.html # index.rhtml
  format.xml  { render :xml => @positions.to_xml }
end

end

Then in the routes.rb I think this is correct , tried to do it logically :

map.resources :positions, :member => {:description => :get}, :controller => “searches”, :path_prefix => “/search/:position_id”,

                        :name_prefix => "position_"

I’m thinking the routes are at least somewhat correct only when i went to /searches I got back this error:

You have a nil object when you didn't expect it!

The error occurred while evaluating nil.parameter_shell

Extracted source (around line #9):

6:
7: <% for position in @positions %>
8: <tr>
9: <td><%= link_to 'Show', position_path(position) %></td>

Stuart

I guess I'm not following what you're trying to do here with the position.

I’ve been trying to gain a better understanding of how to use the CRUD actions. I’ve created a Searches controller and a Search model. Anyway, I came across this blog: http://blog.codahale.com/2006/07/01/

and in particular this quotation -

“Instead, consider using a Search model. Create a search resource that holds all the options for the query. Then you can execute it whenever you want. POST /searches (post data contains query options) would redirect to GET /searches/42 or GET /people/?searches=42. You could even make it so that searches are unbound until execution, like blocks: GET /searches/42?on=people”

My question then does it make sense to structure the controller where ‘new’ or ‘create’ where the search is submitted too and index or show is the results page ? I’d like to get some comments or feedback since this all seems relatively new , some controversy about applying CRUD to search abounds as well.

TIA Stuart

Beast uses the standard index method. In fact, I think these 3 all call the same action:

http://beast.caboo.se/posts http://beast.caboo.se/posts?q=rest http://beast.caboo.se/users/1/posts

It's not really the most elegant solution, but it's a compact way of handling 3 separate actions:

http://svn.techno-weenie.net/projects/beast/trunk/app/controllers/posts_controller.rb