Rails 将搜索结果保存到 CSV 输出



我有一个Rails 3.2.x应用程序,其中我有一个报告控制器,可以搜索呼叫模型。 我整理的代码工作正常,并允许在页面上显示多个条件。 我遇到的问题是将特定搜索结果导出到 CSV 文件。 到目前为止,我只能将整个数据库导出为 CSV 而不是特定的搜索结果。

我想弄清楚如何让我的搜索参数持久存在并能够仅将这些记录导出为 CSV。

这是我的相关代码:

reports_controller.rb

  def index    
     @calls = Call.report(params[:search])
     respond_to do |format|
         format.html do
           @calls = @calls.paginate(:per_page => params[:per_page] || 10, :page => params[:page]).order('incident_number ASC')
         end
         format.csv { send_data @calls.to_csv }
         format.xls  { send_data @calls.to_csv(col_sep: "t") }
       end
   end

呼叫.rb

def self.report(search)
    search ||= { type: "all" }
    # Determine which scope to search by
    results = case search[:type]
              when "open"
                open_status
              when "canceled"
                cancel
              when "closed"
                closed
              when "waitreturn"
                waitreturn
              when "wheelchair"
                wheelchair
              else
                scoped
              end
    results = results.by_unit_name(search[:unit_name]) if search[:unit_name].present?
    results = results.by_service_level(search[:service_level]) if search[:service_level].present?
    results = results.from_facility(search[:transferred_from]) if search[:transferred_from].present?
    results = results.to_facility(search[:transferred_to]) if search[:transferred_to].present?
    # If searching with BOTH a start and end date
    if search[:start_date].present? && search[:end_date].present?
      results = results.search_between(Date.parse(search[:start_date]), Date.parse(search[:end_date]))
      # If search with any other date parameters (including none)
    else
      results = results.search_by_start_date(Date.parse(search[:start_date])) if search[:start_date].present?
      results = results.search_by_end_date(Date.parse(search[:end_date])) if search[:end_date].present?
    end
    results
  end
 def self.to_csv(options = {})
    CSV.generate(options) do |csv|
      csv << ["Call ID", "Caller Name", "Caller Phone", "Call Created At", "Call Status", "Incident Number", "Diagnosis", "Service Level", "Patient Name", "Patient Age", "Patient Sex", "Transfer From", "Transfer To", "Insurance", "Transfer Date", "Unit", "IMX Number"]
      all.each do |call|
        csv << [call.id, call.caller_name, call.caller_phone, call.created_at, call.call_status, call.incident_number, call.nature.determinant, call.service_level.level_of_service, call.patient_name, call.patient_age, call.patient_sex.sex, transfer_from_name(call), transfer_to_name(call), call.insurance.insurance_type, call.transfer_date, call.units.map(&:unit_name).join(", "), call.imx_num]
      end
    end
  end

索引.html.erb

<h2>Reports</h2>
<%= render 'search'%>
<%= render 'results'%>

_search.html.erb

<div>
  <%= form_tag reports_path, :method => 'get' do %>  
    <p>
        <%= select_tag "search[type]", options_for_select([["All Statuses", "all"], ["Open", "open"], ["Closed", "closed"], ["Canceled", "canceled"], ["Wait & Return", "waitreturn"]], selected: params[:search].try(:[], :type)) %>
        <%= select_tag "search[service_level]", options_from_collection_for_select(ServiceLevel.order(:level_of_service), :level_of_service, :level_of_service, selected: params[:search].try(:[], :service_level)), prompt: "All Service Levels" %>
    </p>
    <p>
        <%= text_field_tag "search[start_date]", params[:search].try(:[], :start_date), :placeholder => 'Start Date', :class => 'input-large search-query ', id: 'start_date_select' %>
        to 
        <%= text_field_tag "search[end_date]", params[:search].try(:[], :end_date), :placeholder => 'End Date', :class => 'input-large search-query', id: 'end_date_select'   %>
      </p>
      <p>
        Unit
        <%= select_tag "search[unit_name]", options_from_collection_for_select(Unit.order(:unit_name), :unit_name, :unit_name, selected: params[:search].try(:[], :unit_name)), prompt: "Any Unit" %>
      </p>
      <p>
        From
        <%= select_tag "search[transferred_from]", options_from_collection_for_select(Facility.order(:facility_name), :id, :facility_name, selected: params[:search].try(:[], :transferred_from)), prompt: "Any Facility" %>
        To
      <%= select_tag "search[transferred_to]", options_from_collection_for_select(Facility.order(:facility_name), :id, :facility_name, selected: params[:search].try(:[], :transferred_to)), prompt: "Any Facility" %>
      </p> 
      <p>
        Results Per Page
        <%= select_tag "per_page", options_for_select([["10", 10], ["25", 25] , ["50", 50], ["100", 100], ["All", 100000]], selected: params[:per_page]), class: "span1" %>
        <%= submit_tag "Search", :name => nil, :class => 'btn' %>
      </p>
  <% end %>
</div>

_results.html.erb

<table class="table table-striped">
  <thead>
    <tr>
      <th>Incident Number</th>
      <th>Patient Name</th>
      <th>Transfer Date</th>
      <th>Transferred From</th>
      <th>Transferred To</th>
      <th>Determinant</th>
      <th>Unit</th>
      <th>Insurance</th>
      <th>Cancelation Reason</th>
      <th>IMX Number</th>
      <th></th>
    </tr>
  </thead>
  <tbody>
    <% @calls.each do |c| %>
      <tr>
        <td><%= c.incident_number %></td>
        <td><%= c.patient_name %></td>
        <td><%= c.transfer_date.strftime("%m/%d/%y") %></td>
        <td><%= transferred_from(c) %><br/><%= transferred_from_address(c) %></td>
        <td><%= transferred_to(c) %><br/><%= transferred_to_address(c) %></td>
        <td><%= c.nature.try(:determinant)%></td>
        <td><%= c.units.map(&:unit_name).join(", ") %></td>
        <td><%= c.insurance.try(:insurance_type)%></td>
        <td><%= c.cancel_reason.try(:reason) %></td>
        <td><%= c.imx_num %></td>
        <td><%= link_to 'View', c, :class => 'btn btn-close btn-mini'%></td>
      </tr>
    <% end %>
  </tbody>
</table>
<%= will_paginate @calls, :renderer => BootstrapPagination::Rails %>

在我看来,这是需要持久保存参数并合并它们的代码。

 <%= link_to "Export Results to CSV", reports_path(params.merge(format: "csv")), :class => "btn btn-info" %>

请注意params.merge,它获取所有选定的参数,合并它们,然后将它们传递给控制器。

Call#to_csv方法中,您有:

all.each do |call|
        csv << [call.id, call.caller_name, call.caller_phone, call.created_at, call.call_status, call.incident_number, call.nature.determinant, call.service_level.level_of_service, call.patient_name, call.patient_age, call.patient_sex.sex, transfer_from_name(call), transfer_to_name(call), call.insurance.insurance_type, call.transfer_date, call.units.map(&:unit_name).join(", "), call.imx_num]
      end

我认为all是加载整个数据集的内容,而不是您的过滤版本。

如何传入实际行以转换为CSV,例如:

def self.to_csv(records = [], options = {})
    CSV.generate(options) do |csv|
      csv << ["Call ID", "Caller Name", "Caller Phone", "Call Created At", "Call Status", "Incident Number", "Diagnosis", "Service Level", "Patient Name", "Patient Age", "Patient Sex", "Transfer From", "Transfer To", "Insurance", "Transfer Date", "Unit", "IMX Number"]
      records.each do |call|
        csv << [call.id, call.caller_name, call.caller_phone, call.created_at, call.call_status, call.incident_number, call.nature.determinant, call.service_level.level_of_service, call.patient_name, call.patient_age, call.patient_sex.sex, transfer_from_name(call), transfer_to_name(call), call.insurance.insurance_type, call.transfer_date, call.units.map(&:unit_name).join(", "), call.imx_num]
      end
    end
  end

然后更新控制器:

format.csv { send_data Call.to_csv(@calls }

params.merge在这种情况下可以创造奇迹。此外,为表单提供两个提交按钮也有效。例如,一个是导出 csv。

最新更新