RubyOnRails
RubyOnRails

Reputation: 235

Rails/MongoDb Search and Refine Search Implementation

I have a search functionality in my app which works as the following

  1. Homepage: user selects location from a drop-down and then enters a search key-word and searches to get a set of results
  2. Search Page (REfine Search Options): Once the user hits this page from the above he will be provided with more options to refine the search and narrow the results.

Right now we are implementing as follows but i am assuming as the paramenters increase over 5-7 the number of combinations will increase the number of if-else-elseif statement as well.

#refine search
    @search = params[:search]


    if params[:city].present? && params[:location_ids].present? && params[:search].blank?
      @blood_banks = BloodBank.where(
        { :city_id => "#{@city}" }).where(
        { :location_id.in => params[:location_ids] })
    elsif params[:search].present? && params[:location_ids].blank?
        @blood_banks = BloodBank.where(
          { :bb_name => /#@search/i })
    elsif params[:search].present? && params[:city].present? && params[:location_ids].present?
        @blood_banks = BloodBank.where(
          { :city_id => "#{@city}" }).where(
          { :location_id.in => params[:location_ids] }).where(
          { :bb_name => /#@search/i })
    end 

Which is the best way to implement the same.

How do you achieve below code,

if params[:gender].present?
      if params[:gender] == "male"
      @doctors = Doctor.where( :gender => "Male")
      end
      if params[:gender] == "female"
      @doctors = Doctor.where( :gender => "Female")
      end
      if params[:gender] == "any"
      @doctors = Doctor.where( :gender => "Male") || Doctor.where( :gender => "Female")
      end
end

Upvotes: 2

Views: 218

Answers (1)

mu is too short
mu is too short

Reputation: 434665

Mongoid's where returns a Mongoid::Criteria and Mongoid::Criteria responds to where by returning another Mongoid::Criteria. This means that you can build your query piece by piece:

@blood_banks = BloodBank.all
if params[:city].present?
  @blood_banks = @blood_banks.where(:city_id => params[:city])
end
if params[:location_ids].present?
  @blood_banks = @blood_banks.where(:location_id.in => params[:location_ids])
end
...

As far as the second part goes, if you're searching for any gender then just leave it out entirely, then you can do things like:

@doctors = Doctor.all
genders = { 'male' => 'Male', 'female' => 'Female' }
if genders.has_key? params[:gender]
  @doctors = @doctors.where(:gender => genders[params[:gender]]
end

Searching for any gender is the same not filtering on gender at all so the nil and 'all' cases are the same. Then you can handle the input and :gender values with a simple lookup table.

Upvotes: 1

Related Questions