Rails ActiveRecord中的多个case语句和搜索结果

时间:2014-01-13 22:50:21

标签: ruby ruby-on-rails-3 activerecord case rails-activerecord

我有一个Calls模型,我正在使用Reports Controller进行一些报告。

我可以搜索许多不同的标准和结果链,以便给我预期的搜索结果。我今天添加了一个新的用params搜索:vehicle_type

results = case search[:vehicle_type]
              when "Ambulance"
                ambulance
              when "Wheelchair"
                wheelchair
              else
                scoped
              end

自从我将此case语句添加到report方法后,另一个case语句:type(见下文)不起作用。除此之外,所有其他搜索条件似乎都可以正常工作。

我在这里做错了吗?我的报告方法中不能有多个案例陈述将结果链接在一起吗?

 results = case search[:type]
              when "open"
                open_status
              when "canceled"
                cancel
              when "closed"
                closed
              when "waitreturn"
                waitreturn
              when "wheelchair"
                wheelchair
              else
                scoped
              end

Call.rb

class Call < ActiveRecord::Base 
  before_create :generate_incident_id, :set_dispatched_time
  attr_accessible :caller_address, :caller_street, :caller_state, :caller_zip, :caller_name, :caller_phone, :primary_diagnosis, :unit_assigned,
    :call_status, :incident_number, :facility_from, :facility_to, :unit_id, :nature_id, :facility_id, :caller_email, :facility_from_location,
    :facility_to_location, :patient_name, :patient_age, :patient_sex, :patient_insurance, :transfer_from_id, :transfer_to_id, :transfer_date,
    :dispatched_time, :en_route_time, :on_scene_time, :to_hospital_time, :at_hospital_time, :in_service_time, :service_level_id,
    :special_equipment_ids, :insurance_id, :transfer_from_other, :transfer_to_other, :unit_ids, :patient_sex_id, :incharge_id, :attendant_id,
    :incharge2_id, :attendant2_id, :wait_return, :cancel_reason_id, :parent_call_id, :imx_num, :dispatched_by, :traffic_type

  attr_writer :current_setup
  validates :caller_name, :caller_phone, :patient_name, :patient_age, :nature_id, :insurance_id, :presence => true
  has_many :call_units
  has_many :units, through: :call_units
  belongs_to :nature
  belongs_to :service_level
  belongs_to :patient_sex
  belongs_to :insurance
  has_many :call_special_equipments
  has_many :special_equipments, :through => :call_special_equipments
  belongs_to :transferred_from, :foreign_key => :transfer_from_id, :class_name => 'Facility'
  belongs_to :transferred_to, :foreign_key => :transfer_to_id, :class_name => 'Facility'
  belongs_to :parent_call, class_name: "Call"
  has_many :notes
  belongs_to :cancel_reason

  scope :open_status, where(call_status: "open")
  scope :cancel, where(call_status: "cancel")
  scope :closed, where(call_status: "close")
  scope :waitreturn, where(wait_return: "yes")
  scope :wheelchair, lambda { where(service_level_id: ServiceLevel.find_by_level_of_service("WC").id) }
  scope :bls, lambda { where(service_level_id: ServiceLevel.find_by_level_of_service("BLS").id) }
  scope :als, lambda { where(service_level_id: ServiceLevel.find_by_level_of_service("ALS").id) }
  scope :micu, lambda { where(service_level_id: ServiceLevel.find_by_level_of_service("MICU").id) }
  scope :cct, lambda { where(service_level_id: ServiceLevel.find_by_level_of_service("CCT").id) }
  scope :by_service_level, lambda { |service_level| where(service_level_id: ServiceLevel.find_by_level_of_service(service_level).id) }
  scope :from_facility, lambda { |id| where(transfer_from_id: id) }
  scope :to_facility, lambda { |id| where(transfer_to_id: id) }
  scope :search_between, lambda { |start_date, end_date| where("transfer_date BETWEEN ? AND ?", start_date.beginning_of_day, end_date.end_of_day)}
  scope :search_by_start_date,  lambda { |start_date| where('transfer_date BETWEEN ? AND ?', start_date.beginning_of_day, start_date.end_of_day) }
  scope :search_by_end_date, lambda { |end_date| where('transfer_date BETWEEN ? AND ?', end_date.beginning_of_day, end_date.end_of_day) }
  scope :open_calls, lambda { open_status.includes(:call_units).where(["call_units.unit_id IS NOT NULL"]) }
  scope :unassigned_calls, lambda { open_status.includes(:call_units).where(["call_units.unit_id IS NULL"]).order("calls.id ASC") }
  scope :assigned_calls, lambda { open_status.includes(:call_units).where(["call_units.unit_id IS NOT NULL"]).order("calls.id ASC") }
  scope :by_unit_name, lambda {|unit_name| joins(:units).where('units.unit_name = ?', unit_name)}
  scope :ambulance, lambda {joins(:units).where('units.vehicle_type = ?', "Ambulance")}
  scope :wheelchair, lambda {joins(:units).where('units.vehicle_type = ?', "Wheelchair")}


  #Scope to find scheduled calls
  scope :scheduled_calls, lambda { open_status.includes(:call_units).where(["calls.transfer_date > ?", Time.zone.now.end_of_day]) }

  # Scope to define all open calls scheduled and current assigned to medic in MDT view
  scope :medic_calls, lambda { where(["call_status = ? and call_units.unit_id IS NOT NULL", "open"]).order("id ASC") }

  # Scope to define all open calls scheduled and current for MDT view
  scope :today, lambda { where("transfer_date BETWEEN ? AND ?", Time.zone.now.beginning_of_day, Time.zone.now.end_of_day) }
  scope :year, lambda { where("transfer_date BETWEEN ? AND ?", Time.zone.now.beginning_of_year, Time.zone.now.end_of_year) }
  scope :until_end_of_day, lambda { where("transfer_date < ?", Time.zone.now.end_of_day) }

  def self.search(search)

    if search
      where('incident_number LIKE ? OR patient_name ILIKE ?', "%#{search}%", "%#{search}%")
    else
      scoped
    end
  end

  #Report search logic
  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 = case search[:vehicle_type]
              when "Ambulance"
                ambulance
              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

  #Before create set dispatched time
  def set_dispatched_time
    self.dispatched_time = Time.zone.now
  end

  def dispatch!(unit_ids)
    units << Unit.find(unit_ids)
    set_dispatched_time
    save!
  end

  def closetime!
    self.closed_at = Time.zone.now
  end

  def elapsed_time
    (Time.zone.now - self.dispatched_time).to_i
  end

  def run_time
    (self.closed_at - self.dispatched_time).to_i
  end

  #Auto-increment incident_id
  def generate_incident_id
    incident_year = Time.now.year.to_s[2..-1]
    if Call.count == 0
      self.incident_number = "#{incident_year}-00001"
    else
      last_incident_number = Call.last.incident_number
      number = last_incident_number.split('-')[1].to_i
      number += 1
      self.incident_number = incident_year + '-' + "%05d" % number
    end
  end

  def overdue
    if transfer_date - Time.zone.now < 30.minutes
    end
  end

  def self.to_csv(records = [], options = {})
    CSV.generate(options) do |csv|
      csv << ["Incident Number", "Caller Name", "Caller Phone", "Call Created At", "Call Status", "Wait and Return", "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.incident_number, call.caller_name, call.caller_phone, call.created_at, call.call_status, call.wait_return, 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

  def self.transfer_from_name(call)
    if call.transfer_from_id? 
      call.transferred_from.facility_name 
      else call.transfer_from_other 
    end
  end

  def self.transfer_to_name(call)
    if call.transfer_to_id? 
      call.transferred_to.facility_name 
      else call.transfer_to_other 
    end
  end

  def send_mail(mail_type)
    units.each do |unit|
      CallMailer.send(mail_type, unit.incharge,  self).deliver
      CallMailer.send(mail_type, unit.attendant, self).deliver
    end
  end
end

_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>
        <%= select_tag "search[vehicle_type]", options_for_select([["All Vehicles", "all"], ["Ambulance", "Ambulance"], ["Wheelchair", "Wheelchair"]], selected: params[:search].try(:[], :vehicle_type)) %>
    </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' %> <%= link_to "Export Search Results to CSV", reports_path(params.merge(format: "csv")), :class => "btn btn-info" %>

      </p>
  <% end %>
</div>

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 Call.to_csv(@calls) }
         format.xls  { send_data @calls.to_csv(col_sep: "\t") }
       end
   end

1 个答案:

答案 0 :(得分:1)

您的第二个case语句将覆盖results。您可能希望它结合您现有的范围:

results = case search[:vehicle_type]
              when "Ambulance"
                results.ambulance
              when "Wheelchair"
                results.wheelchair
              else
                results.scoped
              end