title: Multiple case statements and search results in Rails ActiveRecord
body: <p>I have a Calls model where I'm doing some reporting using the Reports Controller.</p>
  
  <p>I can search by many different criteria and the results chain together properly to give me the expected search results.  I added a new one today to search by params :vehicle_type</p>
  
  <pre><code>results = case search[:vehicle_type]
                when "Ambulance"
                  ambulance
                when "Wheelchair"
                  wheelchair
                else
                  scoped
                end
  </code></pre>
  
  <p>Ever since I added this case statement to the report method, the other case statement for :type (see below) does not work.  All other search criteria seem to work fine besides this one.</p>
  
  <p>Am I doing something wrong here?  Can I not have more than one case statement in my report method to chain the results together?</p>
  
  <pre><code> results = case search[:type]
                when "open"
                  open_status
                when "canceled"
                  cancel
                when "closed"
                  closed
                when "waitreturn"
                  waitreturn
                when "wheelchair"
                  wheelchair
                else
                  scoped
                end
  </code></pre>
  
  <p>Call.rb</p>
  
  <pre><code>class Call &lt; 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 =&gt; 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 =&gt; :call_special_equipments
    belongs_to :transferred_from, :foreign_key =&gt; :transfer_from_id, :class_name =&gt; 'Facility'
    belongs_to :transferred_to, :foreign_key =&gt; :transfer_to_id, :class_name =&gt; '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 &gt; ?", 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 &lt; ?", 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? &amp;&amp; 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 &lt;&lt; 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 &lt; 30.minutes
      end
    end
  
    def self.to_csv(records = [], options = {})
      CSV.generate(options) do |csv|
        csv &lt;&lt; ["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 &lt;&lt; [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(&amp;: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
  </code></pre>
  
  <p>_search.html.erb</p>
  
  <pre><code>&lt;div&gt;
    &lt;%= form_tag reports_path, :method =&gt; 'get' do %&gt;  
      &lt;p&gt;
          &lt;%= select_tag "search[type]", options_for_select([["All Statuses", "all"], ["Open", "open"], ["Closed", "closed"], ["Canceled", "canceled"], ["Wait &amp; Return", "waitreturn"]], selected: params[:search].try(:[], :type)) %&gt;
          &lt;%= 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" %&gt;
      &lt;/p&gt;
  
      &lt;p&gt;
          &lt;%= select_tag "search[vehicle_type]", options_for_select([["All Vehicles", "all"], ["Ambulance", "Ambulance"], ["Wheelchair", "Wheelchair"]], selected: params[:search].try(:[], :vehicle_type)) %&gt;
      &lt;/p&gt;
      &lt;p&gt;
          &lt;%= text_field_tag "search[start_date]", params[:search].try(:[], :start_date), :placeholder =&gt; 'Start Date', :class =&gt; 'input-large search-query ', id: 'start_date_select' %&gt;
          to 
          &lt;%= text_field_tag "search[end_date]", params[:search].try(:[], :end_date), :placeholder =&gt; 'End Date', :class =&gt; 'input-large search-query', id: 'end_date_select'   %&gt;
        &lt;/p&gt;
  
        &lt;p&gt;
          Unit
          &lt;%= 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" %&gt;
  
        &lt;/p&gt;
  
        &lt;p&gt;
          From
          &lt;%= 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" %&gt;
          To
        &lt;%= 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" %&gt;
        &lt;/p&gt; 
  
        &lt;p&gt;
          Results Per Page
          &lt;%= select_tag "per_page", options_for_select([["10", 10], ["25", 25] , ["50", 50], ["100", 100], ["All", 100000]], selected: params[:per_page]), class: "span1" %&gt;
          &lt;%= submit_tag "Search", :name =&gt; nil, :class =&gt; 'btn' %&gt; &lt;%= link_to "Export Search Results to CSV", reports_path(params.merge(format: "csv")), :class =&gt; "btn btn-info" %&gt;
  
        &lt;/p&gt;
    &lt;% end %&gt;
  &lt;/div&gt;
  </code></pre>
  
  <p>reports_controller.rb</p>
  
  <pre><code> def index    
       @calls = Call.report(params[:search])
       respond_to do |format|
           format.html do
             @calls = @calls.paginate(:per_page =&gt; params[:per_page] || 10, :page =&gt; 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
  </code></pre>