I need to access the search action but have a different view
(generally RJS) rendered depending on the context of the call.
For example, if called from an order assembly page I might need the
resulting product collection displayed with add to basket links.
Whereas on another page I might need them rendered with add to
purchase order links.
I see to obvious solutions:
1. Define multiple actions within a single resource. They would
essentially have the same code but would call different RJS view code
to render the result.
If going down route 2 I'd probably just repurpose the index action to
check for a search_string param to narrow the results returned.
Both seem less than perfect, although I'm tended towards solution 1.
Although I've only highlighted two view contexts there could be more,
I would suggest 3 or 4 could be common. How would you handle this
situation?
First off, what about using the same search action for each, and using
query parameters to specify the desired behavior? That way you won't
need a new custom action every time you need a new "flavor" of search
call. It's perfectly RESTful to append any query parameters you need
to your actions (/products/search?mode=purchase, or whatever).
However, maybe you really need a separate controller entirely, like a
ProductSearchesController, whose index action can take whatever
parameters you think are appropriate. That might help encapsulate all
of your searching functionality and keep the ProductsController
restful and clean.
G'day Andrew. I agree with Jeff that you should refactor searching out
of ProductsController.
I was in a similar situation to yours, where I needed to search for
[real estate] properties. At first, I created #filter in the Property
model, as well as #filter in PropertiesController. However, as time
went on, this became cumbersome, and filled up the Property model with
many methods that were only loosely related. To make life simpler, I
moved #filter from Property and PropertiesController into a new model,
called PropertyFilter.
Now when I want to search for properties with varying parameters, I
simply create a PropertyFilter instance, and let that work its magic
to perform the search.
If you decide to do this, I recommend having your new model inherit
from ActiveRecord::BaseWithoutTable :
http://agilewebdevelopment.com/plugins/activerecord_base_without_table
It gives the model all of the fancy ActiveRecord methods (like #find,
#validates_*, etc) without the need for a database table behind it.