Skip to content

Commit

Permalink
Add ability to filter locations by activity status
Browse files Browse the repository at this point in the history
Now that the OpenReferral spec requires a `status` field for Services,
it’s possible that all of the Services for a particular Location could
become `inactive` and/or `defunct`.

If that’s the case, I would assume that you would no longer want to
include that Location in search results because you wouldn’t be calling
that location or visiting it if it no longer provides any services.

To enable this filter, I added a boolean `active` field to the
Locations table that automatically gets updated if the Location’s
overall Services status changes.

To only show active locations, pass in the `status=active` parameter.
For example:
https://ohana-api-demo.herokuapp.com/api/search?status=active

To only show inactive locations, pass in `status=inactive`.

For clients that display information about a particular Location, it
might make sense to display a warning or other message if the Location
currently doesn’t have any active services. You can determine if that’s
the case by checking if the Location’s JSON contains an `active`
attribute set to `false`.
Moncef Belyamani committed Oct 23, 2014

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent c50dbfa commit 3f0357f
Showing 14 changed files with 110 additions and 18 deletions.
2 changes: 1 addition & 1 deletion app/controllers/api/v1/root_controller.rb
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ def index
organization_locations_url: "#{api_url}/organizations/{organization}/locations{?page,per_page}",
locations_url: "#{api_locations_url}{?page,per_page}",
location_url: "#{api_locations_url}/{location}",
location_search_url: "#{api_search_index_url}{?category,email,keyword,language,lat_lng,org_name,radius,service_area,page,per_page}"
location_search_url: "#{api_search_index_url}{?category,email,keyword,language,lat_lng,org_name,radius,service_area,status,page,per_page}"
}
render json: json_for_root_endpoint, status: 200
end
2 changes: 1 addition & 1 deletion app/models/address.rb
Original file line number Diff line number Diff line change
@@ -25,6 +25,6 @@ class Address < ActiveRecord::Base
private

def reset_location_coordinates
location.update!(latitude: nil, longitude: nil)
location.update(latitude: nil, longitude: nil)
end
end
9 changes: 8 additions & 1 deletion app/models/concerns/search.rb
Original file line number Diff line number Diff line change
@@ -56,6 +56,10 @@ module Search
module ClassMethods
require 'exceptions'

def status(param)
param == 'active' ? where(active: true) : where(active: false)
end

def language(lang)
where('languages && ARRAY[?]', lang)
end
@@ -93,7 +97,10 @@ def validated_coordinates(lat_lng)
end

def allowed_params(params)
params.slice(:language, :category, :org_name, :email, :keyword, :service_area)
params.slice(
:category, :email, :keyword, :language, :org_name, :service_area,
:status
)
end
end
end
8 changes: 4 additions & 4 deletions app/models/location.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
class Location < ActiveRecord::Base
attr_accessible :accessibility, :admin_emails, :alternate_name, :description,
:emails, :hours, :languages, :latitude, :longitude, :name,
:short_desc, :transportation, :urls, :virtual,
:address_attributes, :contacts_attributes,
attr_accessible :accessibility, :active, :admin_emails, :alternate_name,
:description, :emails, :hours, :languages, :latitude,
:longitude, :name, :short_desc, :transportation, :urls,
:virtual, :address_attributes, :contacts_attributes,
:mail_address_attributes, :phones_attributes,
:services_attributes

2 changes: 1 addition & 1 deletion app/models/organization.rb
Original file line number Diff line number Diff line change
@@ -22,7 +22,7 @@ class Organization < ActiveRecord::Base
extend FriendlyId
friendly_id :name, use: [:history]

after_save :touch_locations
after_save :touch_locations, if: :name_changed?

private

13 changes: 13 additions & 0 deletions app/models/service.rb
Original file line number Diff line number Diff line change
@@ -35,4 +35,17 @@ class Service < ActiveRecord::Base

extend Enumerize
enumerize :status, in: [:active, :defunct, :inactive]

after_save :update_location_status, if: :status_changed?

private

def update_location_status
return if location.active == location_services_active?
location.update_columns(active: location_services_active?)
end

def location_services_active?
location.services.pluck(:status).include?('active')
end
end
8 changes: 4 additions & 4 deletions app/serializers/location_serializer.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
class LocationSerializer < ActiveModel::Serializer
attributes :id, :accessibility, :admin_emails, :alternate_name, :coordinates,
:description, :emails, :hours, :languages, :latitude, :longitude,
:name, :short_desc, :slug, :transportation, :updated_at, :urls,
:url
attributes :id, :active, :accessibility, :admin_emails, :alternate_name,
:coordinates, :description, :emails, :hours, :languages,
:latitude, :longitude, :name, :short_desc, :slug, :transportation,
:updated_at, :urls, :url

has_one :address
has_many :contacts
6 changes: 3 additions & 3 deletions app/serializers/locations_serializer.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
class LocationsSerializer < ActiveModel::Serializer
attributes :id, :admin_emails, :alternate_name, :coordinates, :description,
:latitude, :longitude, :name, :short_desc, :slug, :updated_at,
:urls, :contacts_url, :services_url, :url
attributes :id, :active, :admin_emails, :alternate_name, :coordinates,
:description, :latitude, :longitude, :name, :short_desc, :slug,
:updated_at, :urls, :contacts_url, :services_url, :url

has_one :address
has_one :organization
6 changes: 6 additions & 0 deletions db/migrate/20141023040419_add_active_to_locations.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class AddActiveToLocations < ActiveRecord::Migration
def change
add_column :locations, :active, :boolean, default: true
add_index :locations, :active
end
end
12 changes: 11 additions & 1 deletion db/structure.sql
Original file line number Diff line number Diff line change
@@ -322,7 +322,8 @@ CREATE TABLE locations (
updated_at timestamp without time zone,
tsv_body tsvector,
alternate_name character varying(255),
virtual boolean DEFAULT false
virtual boolean DEFAULT false,
active boolean DEFAULT true
);


@@ -848,6 +849,13 @@ CREATE INDEX index_friendly_id_slugs_on_sluggable_id ON friendly_id_slugs USING
CREATE INDEX index_friendly_id_slugs_on_sluggable_type ON friendly_id_slugs USING btree (sluggable_type);


--
-- Name: index_locations_on_active; Type: INDEX; Schema: public; Owner: -; Tablespace:
--

CREATE INDEX index_locations_on_active ON locations USING btree (active);


--
-- Name: index_locations_on_languages; Type: INDEX; Schema: public; Owner: -; Tablespace:
--
@@ -1085,3 +1093,5 @@ INSERT INTO schema_migrations (version) VALUES ('20141017154640');

INSERT INTO schema_migrations (version) VALUES ('20141021195019');

INSERT INTO schema_migrations (version) VALUES ('20141023040419');

30 changes: 30 additions & 0 deletions spec/api/get_locations_spec.rb
Original file line number Diff line number Diff line change
@@ -258,4 +258,34 @@
expect(location_keys).to include('coordinates')
end
end

context 'when location has no active services' do
it 'sets the active field to false' do
location = create(:location)

attrs = attributes_for(:service)

location.services.create!(attrs.merge(status: 'inactive'))
location.services.create!(attrs.merge(status: 'inactive'))

get api_locations_url(subdomain: ENV['API_SUBDOMAIN'])

expect(json.first['active']).to eq false
end
end

context 'when location has at least one active service' do
it 'sets the active field to true' do
location = create(:location)

attrs = attributes_for(:service)

location.services.create!(attrs)
location.services.create!(attrs.merge(status: 'inactive'))

get api_locations_url(subdomain: ENV['API_SUBDOMAIN'])

expect(json.first['active']).to eq true
end
end
end
2 changes: 1 addition & 1 deletion spec/api/patch_organization_spec.rb
Original file line number Diff line number Diff line change
@@ -62,7 +62,7 @@
to eq('http://codeforamerica.github.io/ohana-api-docs/')
end

it 'updates the search index when organization changes' do
it 'updates the search index when organization name changes' do
patch(
api_organization_url(@org, subdomain: ENV['API_SUBDOMAIN']),
name: 'Code for America'
2 changes: 1 addition & 1 deletion spec/api/root_endpoint_spec.rb
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@
'organization_locations_url' => "#{api_url}/organizations/{organization}/locations{?page,per_page}",
'locations_url' => "#{api_locations_url}{?page,per_page}",
'location_url' => "#{api_locations_url}/{location}",
'location_search_url' => "#{api_search_index_url}{?category,email,keyword,language,lat_lng,org_name,radius,service_area,page,per_page}"
'location_search_url' => "#{api_search_index_url}{?category,email,keyword,language,lat_lng,org_name,radius,service_area,status,page,per_page}"
}
expect(json).to eq(hash)
end
26 changes: 26 additions & 0 deletions spec/api/search/location_status_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
require 'rails_helper'

describe "GET 'search'" do

context 'with status parameter' do
before(:each) do
create(:nearby_loc)
@location = create(:location)
@attrs = attributes_for(:service)
end

it 'only returns active locations when status=active' do
@location.services.create!(@attrs.merge(status: 'inactive'))
get 'api/search?status=active'
expect(json.length).to eq(1)
expect(json.first['name']).to eq 'Library'
end

it 'only returns inactive locations when status != active' do
@location.services.create!(@attrs.merge(status: 'inactive'))
get 'api/search?status=inactive'
expect(json.length).to eq(1)
expect(json.first['name']).to eq 'VRS Services'
end
end
end

0 comments on commit 3f0357f

Please sign in to comment.