Override the respond_to format with form button in

2019-02-25 08:10发布

问题:

I have a set of reports that are displayed in various formats using the Rails call "respond_to", such that if the URL ends in CSV or JSON, the report is generated in that format.

I had a request to make a download button to make grabbing reports easier, but since the reports have customizations like date ranges, I need to be able to submit one form and specify a response format in the form. Is this possible? How can it be done?

Form Code:

<%= form_tag('', method: 'get') do %>
    <%= hidden_field_tag('s',params[:s]) %>
    <%= select_tag "date_interval", options_from_collection_for_select(Admin::ReportController::DATE_INTERVALS.to_a, 'first', 'last') %>
    <%= label_tag('start_at','Start at') %> <%= text_field_tag('start_at', @start_at, class: 'datetimeselect') %>
    <%= label_tag('end_at','End at') %> <%= text_field_tag('end_at', @end_at, class: 'datetimeselect') %>
    <script>
        $('.datetimeselect').datetimepicker({format: "Y-m-d H O"});
    </script>
    <%= button_tag( 'HTML', :value => 'html', :name => 'run' ) %>
    <%= button_tag( 'CSV', :value => 'csv', :name => 'run' ) %>
    <%= button_tag( 'JSON', :value => 'json', :name => 'run' ) %>
<% end %>

Note the 3 button tags above where the value is the format and the param 'run' would be used to override the route-based formats.

Respond-to code (runs after report is generated in the controller):

  def format_results
    respond_to do |format|
      format.html {
        # default render of HTML table
      }
      format.json {
        render json: { results: @results[:results], header: @results[:header], name: @results[:name], stats: { rows: @results.count } }, layout: false
      }
      format.csv {
        render text: report_to_csv( @results ), content_type: 'text/csv', layout: false
      }
    end
  end

When I specify the extension in the URL, that works, what I'm looking for is a way to override that using a button value in the buttons named "run" above.

Thank you in advance!

回答1:

I can finally respond to my own question, now. So here's the answer:

I figured out how this can be accomplished. You can set the name of the buttons to be "format" and set the value to the extension that you would append to the URL.

 <%= button_tag( 'HTML', :value => 'html', :name => 'format' ) %>
 <%= button_tag( 'CSV', :value => 'csv', :name => 'format' ) %>
 <%= button_tag( 'JSON', :value => 'json', :name => 'format' ) %> 

Simply changing the params[:format] doesn't work. You have to pass it in before your action runs.