ruby-on-railsrubyrespond-to

how to DRY a respond_to that is the same in all actions?


I have a controller that will server widgets:

class WidgetsController < ApplicationController
  def widget1
    respond_to do |format|
      format.html
      format.js { render js: js_constructor }
    end
  end

  def widget2
    respond_to do |format|
      format.html
      format.js { render js: js_constructor }
    end
  end

  private
  def js_constructor
    content = render_to_string(params[:action], layout: false)
    "document.write(#{content.to_json})"
  end
end

This controller will get bigger, so I would like to avoid repeating this block of code in all actions:

respond_to do |format|
  format.html
  format.js { render js: js_constructor }
end

Any idea?

EDIT: just to give some context...

The route is flexible/dynamic: get 'widgets/:action', to: 'widgets#:action'

So, if I visit widgets/widget1 it will render the view widget1.html.erb.

If I include the script in another server it will construct the widget1 over there:

<script type='text/javascript' src='http://localhost:3000/widgets/widget1.js'></script>

Solution

  • I would write a single action that takes the "view" as a parameter. You're basically doing a #show action that renders different views.

    get 'widgets/:template', to: 'widgets#show'

    class WidgetsController < ApplicationController
      def show
        respond_to do |format|
          format.html { render params.require(:template) }
          format.js { render js: js_constructor }
        end
      end
    
      private
      def js_constructor
        content = render_to_string(params.require(:template), layout: false)
        "document.write(#{content.to_json})"
      end
    end