Commit 5b35ca5

mo khan <mo@mokhan.ca>
2016-05-03 04:03:50
create search scopes for gym.
1 parent 13ea080
Changed files (5)
app/controllers/gyms_controller.rb
@@ -2,7 +2,7 @@ class GymsController < ApplicationController
   before_action :provide_search_path
 
   def index
-    @gyms = Gym.closest_to(current_session.location).includes(:location)
+    @gyms = Gym.search_with(params).closest_to(current_session.location).includes(:location)
   end
 
   def new
app/models/gym.rb
@@ -12,4 +12,20 @@ class Gym < ActiveRecord::Base
       all
     end
   end
+
+  scope :search, ->(query) do
+    sql = 'UPPER(gyms.name) LIKE :query' +
+      ' OR UPPER(locations.city) LIKE :query' +
+      ' OR UPPER(locations.region) LIKE :query' +
+      ' OR UPPER(locations.country) LIKE :query'
+    joins(:location).where(sql, { query: "%#{query.upcase}%" })
+  end
+
+  scope :search_with, ->(params) do
+    if params[:q].present?
+      search(params[:q])
+    else
+      all
+    end
+  end
 end
spec/controllers/gyms_controller_spec.rb
@@ -8,8 +8,8 @@ describe GymsController do
   end
 
   describe "#index" do
-    let(:sait) { create(:gym, name: 'sait') }
-    let(:world_health) { create(:gym, name: 'world health') }
+    let!(:sait) { create(:gym, name: 'sait') }
+    let!(:world_health) { create(:gym, name: 'world health') }
 
     it 'returns a list of gyms' do
       get :index
@@ -17,6 +17,13 @@ describe GymsController do
       expect(assigns(:gyms)).to match_array([sait, world_health])
       expect(response).to be_ok
     end
+
+    it 'returns matching results' do
+      get :index, q: 'sait'
+
+      expect(assigns(:gyms)).to match_array([sait])
+      expect(response).to be_ok
+    end
   end
 
   describe "#new" do
spec/models/gym_spec.rb
@@ -49,4 +49,35 @@ describe Gym do
       expect(results).to match_array([calgary_gym, edmonton_gym])
     end
   end
+
+  describe '.search_with' do
+    let!(:calgary_gym) { create(:gym, name: 'SAIT', location: create(:calgary)) }
+    let!(:edmonton_gym) { create(:gym, name: 'NAIT', location: create(:edmonton)) }
+    let!(:portland_gym) { create(:gym, name: '24 Hour Fitness', location: create(:portland)) }
+
+    it 'returns all gyms' do
+      results = Gym.search_with({})
+      expect(results).to match_array([calgary_gym, edmonton_gym, portland_gym])
+    end
+
+    it 'returns gyms with a matching name' do
+      results = Gym.search_with(q: 'sait')
+      expect(results).to match_array([calgary_gym])
+    end
+
+    it 'returns all gyms from a city' do
+      results = Gym.search_with(q: 'calgary')
+      expect(results).to match_array([calgary_gym])
+    end
+
+    it 'returns all gyms from a region' do
+      results = Gym.search_with(q: 'AB')
+      expect(results).to match_array([calgary_gym, edmonton_gym])
+    end
+
+    it 'returns all gyms from a country' do
+      results = Gym.search_with(q: 'US')
+      expect(results).to match_array([portland_gym])
+    end
+  end
 end
spec/factories.rb
@@ -88,6 +88,13 @@ FactoryGirl.define do
       region { "AB" }
       country { "CA" }
     end
+    factory :portland do
+      latitude { 45.542415 }
+      longitude { -122.7244614 }
+      city { "Portland" }
+      region { "OR" }
+      country { "US" }
+    end
     factory :no_where do
       latitude { 0.0 }
       longitude { 0.0 }