JJK
JJK

Reputation: 179

Rails - Multiple remote forms hitting same controller action?

I'm working on an application in which a certain model is updated from a number of different locations using remote forms. I'm looking for a pattern to dynamically call the right JS callback after updating this model.

With a normal form this can be solved by passing a redirect url in the form itself and then redirecting to this url in the controller. The remote form side is harder: Should I pass a file name? Should I pass an arbitrary string and then switch on that string in a single .js.erb file? Any other suggestions?

Is this just a sign that the application should be restructured to prevent updating the same model from more than one location?

Upvotes: 0

Views: 427

Answers (1)

Pierre Pretorius
Pierre Pretorius

Reputation: 2909

No it's fine If you can call the same controller action from different locations.

Your options:

1) Preferably this controller action can give the same response and will work for the different locations, ex. it just updates a container with a id which is present in all those locations.

2) You noted that redirects made things easy in the past, consider adding the following to your application controller:

def js_redirect_to(path, flash_messages = {})
  flash_messages.each { |type, message| flash[type] = message }

  respond_to do |format|
    format.js { render :js => "window.top.location='#{path}';" }
  end
end

This is the same signature as the normal redirect_to, it just allows you to redirect from a js request. Note that if you use turbolinks the js should be 'Turbolinks.visit(url);'.

3) If you really can't handle it generically like the options above, you could pass your JS namespace of the location you are submitting from in the form, and the controller calls the same method for all locations, it's just a different namespace. Ex:

Let say one location is from Pet administration, then in assets pet.js:

var pet = {
  load = function() {
    your page load js...
  },

  ... more functions...

  post_callback = function(html_segment1, html_segment2) {
    this is where you handle the form callback for pets...
    $('some_element').html(html_segment1);
    $('another_element').html(html_segment2);
  }
}

Construct more like these for other locations of your app. Using JS namespaces like this is anyway a good idea. Then your form submits a parameter :location => :pet to the controller, which responds with:

... your JS code that all pages should execute...
html_segment1 = "<%= escape_javascript(render 'some_partial') %>";
html_segment2 = "<%= escape_javascript(render 'other_partial') %>";
<%= @location %>.post_callback(html_segment1, html_segment2);

4) Use a widget gem, most popular is apotomo or cells.

5) Just use a case in the controller to render different views.

Hope this helps, let me know if you need clarification.

Upvotes: 2

Related Questions