From 28801bd1e2441aba1cc1cce1552a96b251fab6e8 Mon Sep 17 00:00:00 2001 From: Moncef Belyamani Date: Tue, 9 Sep 2014 01:15:20 -0400 Subject: [PATCH] Add support for searching on multiple languages. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Example: http://ohana-api-demo.herokuapp.com/api/search?language[]=Filipino%20(Ta galog)&language[]=Hindi This will return locations whose languages field contain either “Filipino (Tagalog)” OR “Hindi”. Run `bin/rake db:migrate` to update the DB. This PR converts the `languages` field from text to the Postgres Array type. If for some reason you want to rollback this DB change, you’ll first need to add the following line in `app/models/location.rb`: ``` serialize :languages, Array ``` Then you can rollback: ``` bin/rake db:rollback ``` You’ll then need to update the `language` search method to its previous query, and update `spec/api/search/language_spec.rb`. --- .travis.yml | 2 +- app/models/concerns/search.rb | 5 +- app/models/location.rb | 6 - app/validators/service_area_validator.rb | 2 +- ...9031145_convert_languages_to_array_type.rb | 29 ++++ db/structure.sql | 143 +++++++++--------- spec/api/search/language_spec.rb | 25 +++ spec/api/search_spec.rb | 7 - spec/factories/locations.rb | 5 +- spec/models/location_spec.rb | 1 - 10 files changed, 135 insertions(+), 90 deletions(-) create mode 100644 db/migrate/20140909031145_convert_languages_to_array_type.rb create mode 100644 spec/api/search/language_spec.rb diff --git a/.travis.yml b/.travis.yml index 558354032..6c15fe362 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ bundler_args: --without assets:development:production language: ruby rvm: - - 2.1.1 + - 2.1.2 addons: postgresql: "9.3" before_script: diff --git a/app/models/concerns/search.rb b/app/models/concerns/search.rb index 1b3dccdbc..42826fbb2 100644 --- a/app/models/concerns/search.rb +++ b/app/models/concerns/search.rb @@ -2,7 +2,6 @@ module Search extend ActiveSupport::Concern included do - scope :language, ->(language) { where('languages @@ :q', q: language) } scope :keyword, ->(keyword) { keyword_search(keyword) } scope :category, ->(category) { joins(services: :categories).where(categories: { name: category }) } @@ -57,6 +56,10 @@ module Search module ClassMethods require 'exceptions' + def language(lang) + where('languages && ARRAY[?]', lang) + end + def service_area(sa) joins(:services).where('services.service_areas @@ :q', q: sa) end diff --git a/app/models/location.rb b/app/models/location.rb index 5e0dee548..fba7b7d5c 100644 --- a/app/models/location.rb +++ b/app/models/location.rb @@ -95,12 +95,6 @@ class Location < ActiveRecord::Base serialize :emails, Array - serialize :languages, Array - # enumerize :languages, in: [:arabic, :cantonese, :french, :german, - # :mandarin, :polish, :portuguese, :russian, :spanish, :tagalog, :urdu, - # :vietnamese, - # ], multiple: true, scope: true - serialize :urls, Array auto_strip_attributes :description, :hours, :name, :short_desc, diff --git a/app/validators/service_area_validator.rb b/app/validators/service_area_validator.rb index c53b76fbc..482a63aba 100644 --- a/app/validators/service_area_validator.rb +++ b/app/validators/service_area_validator.rb @@ -1,6 +1,6 @@ class ServiceAreaValidator < ActiveModel::EachValidator def validate_each(record, attribute, value) - return if value.blank? + return if value.blank? || SETTINGS[:valid_service_areas].blank? default_message = "#{value} #{I18n.t('errors.messages.invalid_service_area')}" unless SETTINGS[:valid_service_areas].include?(value) diff --git a/db/migrate/20140909031145_convert_languages_to_array_type.rb b/db/migrate/20140909031145_convert_languages_to_array_type.rb new file mode 100644 index 000000000..ed823807b --- /dev/null +++ b/db/migrate/20140909031145_convert_languages_to_array_type.rb @@ -0,0 +1,29 @@ +class ConvertLanguagesToArrayType < ActiveRecord::Migration + def up + execute "drop index locations_languages" + change_column :locations, :languages, "text[] USING (string_to_array(languages, '\n- '))", default: [] + add_index :locations, :languages, using: 'gin' + + Location.find_each do |loc| + if loc.languages.nil? + loc.update(languages: []) + else + clean_langs = loc.languages.select { |lang| lang != '---' }. + map { |lang| lang.strip.gsub("\n", '') } + loc.update(languages: clean_langs) + end + end + end + + def down + execute "drop index index_locations_on_languages" + change_column :locations, :languages, "text USING (array_to_string(languages, ','))" + + Location.find_each do |loc| + next if loc.languages.blank? + loc.update(languages: loc.languages.split(',')) + end + + execute "create index locations_languages on locations using gin(to_tsvector('english', languages))" + end +end diff --git a/db/structure.sql b/db/structure.sql index 800c9d48b..0e1581fe4 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -70,7 +70,7 @@ SET default_tablespace = ''; SET default_with_oids = false; -- --- Name: addresses; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: addresses; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE addresses ( @@ -105,7 +105,7 @@ ALTER SEQUENCE addresses_id_seq OWNED BY addresses.id; -- --- Name: admins; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: admins; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE admins ( @@ -151,7 +151,7 @@ ALTER SEQUENCE admins_id_seq OWNED BY admins.id; -- --- Name: api_applications; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: api_applications; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE api_applications ( @@ -186,7 +186,7 @@ ALTER SEQUENCE api_applications_id_seq OWNED BY api_applications.id; -- --- Name: categories; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: categories; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE categories ( @@ -220,7 +220,7 @@ ALTER SEQUENCE categories_id_seq OWNED BY categories.id; -- --- Name: categories_services; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: categories_services; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE categories_services ( @@ -230,7 +230,7 @@ CREATE TABLE categories_services ( -- --- Name: contacts; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: contacts; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE contacts ( @@ -267,7 +267,7 @@ ALTER SEQUENCE contacts_id_seq OWNED BY contacts.id; -- --- Name: faxes; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: faxes; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE faxes ( @@ -300,7 +300,7 @@ ALTER SEQUENCE faxes_id_seq OWNED BY faxes.id; -- --- Name: friendly_id_slugs; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: friendly_id_slugs; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE friendly_id_slugs ( @@ -332,7 +332,7 @@ ALTER SEQUENCE friendly_id_slugs_id_seq OWNED BY friendly_id_slugs.id; -- --- Name: locations; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: locations; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE locations ( @@ -345,7 +345,7 @@ CREATE TABLE locations ( hours text, latitude double precision, longitude double precision, - languages text, + languages text[] DEFAULT '{}'::text[], name text, short_desc text, transportation text, @@ -377,7 +377,7 @@ ALTER SEQUENCE locations_id_seq OWNED BY locations.id; -- --- Name: mail_addresses; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: mail_addresses; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE mail_addresses ( @@ -413,7 +413,7 @@ ALTER SEQUENCE mail_addresses_id_seq OWNED BY mail_addresses.id; -- --- Name: organizations; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: organizations; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE organizations ( @@ -446,7 +446,7 @@ ALTER SEQUENCE organizations_id_seq OWNED BY organizations.id; -- --- Name: phones; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: phones; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE phones ( @@ -482,7 +482,7 @@ ALTER SEQUENCE phones_id_seq OWNED BY phones.id; -- --- Name: schema_migrations; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: schema_migrations; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE schema_migrations ( @@ -491,7 +491,7 @@ CREATE TABLE schema_migrations ( -- --- Name: services; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: services; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE services ( @@ -534,7 +534,7 @@ ALTER SEQUENCE services_id_seq OWNED BY services.id; -- --- Name: users; Type: TABLE; Schema: public; Owner: -; Tablespace: +-- Name: users; Type: TABLE; Schema: public; Owner: -; Tablespace: -- CREATE TABLE users ( @@ -670,7 +670,7 @@ ALTER TABLE ONLY users ALTER COLUMN id SET DEFAULT nextval('users_id_seq'::regcl -- --- Name: addresses_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: addresses_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY addresses @@ -678,7 +678,7 @@ ALTER TABLE ONLY addresses -- --- Name: admins_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: admins_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY admins @@ -686,7 +686,7 @@ ALTER TABLE ONLY admins -- --- Name: api_applications_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: api_applications_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY api_applications @@ -694,7 +694,7 @@ ALTER TABLE ONLY api_applications -- --- Name: categories_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: categories_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY categories @@ -702,7 +702,7 @@ ALTER TABLE ONLY categories -- --- Name: contacts_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: contacts_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY contacts @@ -710,7 +710,7 @@ ALTER TABLE ONLY contacts -- --- Name: faxes_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: faxes_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY faxes @@ -718,7 +718,7 @@ ALTER TABLE ONLY faxes -- --- Name: friendly_id_slugs_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: friendly_id_slugs_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY friendly_id_slugs @@ -726,7 +726,7 @@ ALTER TABLE ONLY friendly_id_slugs -- --- Name: locations_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: locations_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY locations @@ -734,7 +734,7 @@ ALTER TABLE ONLY locations -- --- Name: mail_addresses_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: mail_addresses_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY mail_addresses @@ -742,7 +742,7 @@ ALTER TABLE ONLY mail_addresses -- --- Name: organizations_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: organizations_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY organizations @@ -750,7 +750,7 @@ ALTER TABLE ONLY organizations -- --- Name: phones_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: phones_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY phones @@ -758,7 +758,7 @@ ALTER TABLE ONLY phones -- --- Name: services_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: services_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY services @@ -766,7 +766,7 @@ ALTER TABLE ONLY services -- --- Name: users_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: +-- Name: users_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: -- ALTER TABLE ONLY users @@ -774,252 +774,252 @@ ALTER TABLE ONLY users -- --- Name: categories_name; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: categories_name; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX categories_name ON categories USING gin (to_tsvector('english'::regconfig, name)); -- --- Name: index_addresses_on_location_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_addresses_on_location_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_addresses_on_location_id ON addresses USING btree (location_id); -- --- Name: index_admins_on_confirmation_token; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_admins_on_confirmation_token; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE UNIQUE INDEX index_admins_on_confirmation_token ON admins USING btree (confirmation_token); -- --- Name: index_admins_on_email; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_admins_on_email; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE UNIQUE INDEX index_admins_on_email ON admins USING btree (email); -- --- Name: index_admins_on_reset_password_token; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_admins_on_reset_password_token; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE UNIQUE INDEX index_admins_on_reset_password_token ON admins USING btree (reset_password_token); -- --- Name: index_api_applications_on_api_token; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_api_applications_on_api_token; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE UNIQUE INDEX index_api_applications_on_api_token ON api_applications USING btree (api_token); -- --- Name: index_api_applications_on_user_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_api_applications_on_user_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_api_applications_on_user_id ON api_applications USING btree (user_id); -- --- Name: index_categories_on_ancestry; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_categories_on_ancestry; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_categories_on_ancestry ON categories USING btree (ancestry); -- --- Name: index_categories_on_slug; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_categories_on_slug; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE UNIQUE INDEX index_categories_on_slug ON categories USING btree (slug); -- --- Name: index_categories_services_on_category_id_and_service_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_categories_services_on_category_id_and_service_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE UNIQUE INDEX index_categories_services_on_category_id_and_service_id ON categories_services USING btree (category_id, service_id); -- --- Name: index_categories_services_on_service_id_and_category_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_categories_services_on_service_id_and_category_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE UNIQUE INDEX index_categories_services_on_service_id_and_category_id ON categories_services USING btree (service_id, category_id); -- --- Name: index_contacts_on_location_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_contacts_on_location_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_contacts_on_location_id ON contacts USING btree (location_id); -- --- Name: index_faxes_on_location_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_faxes_on_location_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_faxes_on_location_id ON faxes USING btree (location_id); -- --- Name: index_friendly_id_slugs_on_slug_and_sluggable_type; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_friendly_id_slugs_on_slug_and_sluggable_type; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE UNIQUE INDEX index_friendly_id_slugs_on_slug_and_sluggable_type ON friendly_id_slugs USING btree (slug, sluggable_type); -- --- Name: index_friendly_id_slugs_on_sluggable_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_friendly_id_slugs_on_sluggable_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_friendly_id_slugs_on_sluggable_id ON friendly_id_slugs USING btree (sluggable_id); -- --- Name: index_friendly_id_slugs_on_sluggable_type; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_friendly_id_slugs_on_sluggable_type; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_friendly_id_slugs_on_sluggable_type ON friendly_id_slugs USING btree (sluggable_type); -- --- Name: index_locations_on_latitude_and_longitude; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_locations_on_languages; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- + +CREATE INDEX index_locations_on_languages ON locations USING gin (languages); + + +-- +-- Name: index_locations_on_latitude_and_longitude; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_locations_on_latitude_and_longitude ON locations USING btree (latitude, longitude); -- --- Name: index_locations_on_organization_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_locations_on_organization_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_locations_on_organization_id ON locations USING btree (organization_id); -- --- Name: index_locations_on_slug; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_locations_on_slug; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE UNIQUE INDEX index_locations_on_slug ON locations USING btree (slug); -- --- Name: index_locations_on_tsv_body; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_locations_on_tsv_body; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_locations_on_tsv_body ON locations USING gin (tsv_body); -- --- Name: index_mail_addresses_on_location_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_mail_addresses_on_location_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_mail_addresses_on_location_id ON mail_addresses USING btree (location_id); -- --- Name: index_organizations_on_slug; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_organizations_on_slug; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE UNIQUE INDEX index_organizations_on_slug ON organizations USING btree (slug); -- --- Name: index_phones_on_location_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_phones_on_location_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_phones_on_location_id ON phones USING btree (location_id); -- --- Name: index_services_on_location_id; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_services_on_location_id; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX index_services_on_location_id ON services USING btree (location_id); -- --- Name: index_users_on_confirmation_token; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_users_on_confirmation_token; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE UNIQUE INDEX index_users_on_confirmation_token ON users USING btree (confirmation_token); -- --- Name: index_users_on_email; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_users_on_email; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE UNIQUE INDEX index_users_on_email ON users USING btree (email); -- --- Name: index_users_on_reset_password_token; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: index_users_on_reset_password_token; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE UNIQUE INDEX index_users_on_reset_password_token ON users USING btree (reset_password_token); -- --- Name: locations_admin_emails; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: locations_admin_emails; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX locations_admin_emails ON locations USING gin (to_tsvector('english'::regconfig, admin_emails)); -- --- Name: locations_description; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: locations_description; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX locations_description ON locations USING gin (to_tsvector('english'::regconfig, description)); -- --- Name: locations_emails; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: locations_emails; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX locations_emails ON locations USING gin (to_tsvector('english'::regconfig, emails)); -- --- Name: locations_languages; Type: INDEX; Schema: public; Owner: -; Tablespace: --- - -CREATE INDEX locations_languages ON locations USING gin (to_tsvector('english'::regconfig, languages)); - - --- --- Name: locations_name; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: locations_name; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX locations_name ON locations USING gin (to_tsvector('english'::regconfig, name)); -- --- Name: locations_urls; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: locations_urls; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX locations_urls ON locations USING gin (to_tsvector('english'::regconfig, urls)); -- --- Name: organizations_name; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: organizations_name; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX organizations_name ON organizations USING gin (to_tsvector('english'::regconfig, name)); -- --- Name: services_service_areas; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: services_service_areas; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE INDEX services_service_areas ON services USING gin (to_tsvector('english'::regconfig, service_areas)); -- --- Name: unique_schema_migrations; Type: INDEX; Schema: public; Owner: -; Tablespace: +-- Name: unique_schema_migrations; Type: INDEX; Schema: public; Owner: -; Tablespace: -- CREATE UNIQUE INDEX unique_schema_migrations ON schema_migrations USING btree (version); @@ -1086,3 +1086,4 @@ INSERT INTO schema_migrations (version) VALUES ('20140630171418'); INSERT INTO schema_migrations (version) VALUES ('20140829154350'); +INSERT INTO schema_migrations (version) VALUES ('20140909031145'); diff --git a/spec/api/search/language_spec.rb b/spec/api/search/language_spec.rb new file mode 100644 index 000000000..9c7dc6a56 --- /dev/null +++ b/spec/api/search/language_spec.rb @@ -0,0 +1,25 @@ +require 'rails_helper' + +describe "GET 'search'" do + + context 'with language parameter' do + before(:each) do + create(:nearby_loc) + create(:farmers_market_loc) + end + + it 'finds matching locations when language is a String' do + get api_search_index_url( + language: 'Arabic', + subdomain: ENV['API_SUBDOMAIN'] + ) + expect(json.length).to eq(1) + expect(json.first['name']).to eq('Library') + end + + it 'finds matching locations when language is an Array' do + get 'api/search?language[]=Spanish&language[]=French' + expect(json.length).to eq(2) + end + end +end diff --git a/spec/api/search_spec.rb b/spec/api/search_spec.rb index 8b55a9b41..6ff5e33ca 100644 --- a/spec/api/search_spec.rb +++ b/spec/api/search_spec.rb @@ -188,13 +188,6 @@ end end - context 'with language parameter' do - it 'finds organizations that match the language' do - get api_search_index_url(keyword: 'library', language: 'arabic', subdomain: ENV['API_SUBDOMAIN']) - expect(json.first['name']).to eq('Library') - end - end - context 'with keyword and location parameters' do it 'only returns locations matching both parameters' do get api_search_index_url(keyword: 'books', location: 'Burlingame', subdomain: ENV['API_SUBDOMAIN']) diff --git a/spec/factories/locations.rb b/spec/factories/locations.rb index d6f54ac94..abf4b73be 100644 --- a/spec/factories/locations.rb +++ b/spec/factories/locations.rb @@ -40,7 +40,7 @@ latitude 37.5808591 longitude(-122.343072) association :address, factory: :near - languages %w(spanish Arabic) + languages %w(Spanish Arabic) association :organization, factory: :nearby_org end @@ -58,6 +58,7 @@ short_desc 'short description' latitude 37.3180168 longitude(-122.2743951) + languages %w(French Tagalog) association :address, factory: :far_west organization end @@ -69,7 +70,7 @@ latitude 37.6047797 longitude(-122.3984501) association :address, factory: :far - languages %w(spanish Arabic) + languages %w(Spanish Arabic) organization end diff --git a/spec/models/location_spec.rb b/spec/models/location_spec.rb index 06ab2fd53..c6d6da965 100644 --- a/spec/models/location_spec.rb +++ b/spec/models/location_spec.rb @@ -71,7 +71,6 @@ it { is_expected.to serialize(:admin_emails).as(Array) } it { is_expected.to serialize(:emails).as(Array) } - it { is_expected.to serialize(:languages).as(Array) } it { is_expected.to serialize(:urls).as(Array) } describe 'invalidations' do