views:

1976

answers:

4

I have a controller method that returns a list for a drop down that gets rendered in a partial, but depending on where the partial is being used, the RJS template needs to be different. Can I pass a parameter to the controller that will determine which RJS gets used?

Here is the controller method, it is very simple:

def services
   respond_to do |format|
     format.js {
       @type     = HospitalCriteria.find_by_id(params[:type_id])
       @services = @type.children.all
     }
   end
end

And here is the rjs template the gets rendered automatically

page.replace_html 'select_service', :partial => 'hospital/services'
page.replace_html 'select_condition', :partial => 'hospital/conditions'
page.replace_html 'select_procedure', :partial => 'hospital/procedures'

page << 'if ($("chosenType") != null) {'
  page.replace_html 'chosenType', @type.name
  page.replace_html 'chosenService', 'Selected Service'
  page.replace_html 'chosenCondition', 'Selected Condition'
  page.replace_html 'chosenProcedure', 'Selected Procedure'
page << '}'
+1  A: 

something like:

if params[:use_alternate]
  render :template => alternate.rjs and return
end
Mike Breen
+3  A: 

I like Mike's response, but something to think about here from a design perspective:

It sounds to me like this should be in the view layer - if the action is semantically the same, but the presentation is different, perhaps having two different rjs partials and doing something like below is more compliant with MVC?

if params[:use_alternate]
  render :partial => "case_1.rjs"
else
  render :partial => "case_2.rjs"
end
danpickett
A: 

To keep things clean, I'd have two controller methods that render the two different RJSs. I'd then set @type and @services in a common protected method that the two controller methods call.

In my mind you are asking for something different in each case so call a different controller method. Passing in a flag to change the way the method works is just a hack and won't scale well when you have 3, 4 or 5 places. Even though you'll generate more code, it will be easier to maintain.

RichH
+2  A: 

What about placing the conditional logic in one rjs template?

# services.rjs

if @type == "your conditions"
  # your rjs updates
else
  # your other rjs updates
end

This gives you a cleaner controller and saves you the headache of maintaining multiple rjs templates.

JasonOng
All of the solutions work but I think this is the cleanest.
Kyle Boon