1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
class Gym < ApplicationRecord
validates_presence_of :name
has_one :location, as: :locatable, dependent: :destroy
accepts_nested_attributes_for :location
acts_as_mappable through: :location
delegate :full_address, to: :location, allow_nil: true
scope :closest_to, ->(location, distance: 100) do
if location.present? && location.coordinates.present?
joins(:location).
within(distance, units: :kms, origin: location.coordinates)
else
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"
].join(" ")
joins(:location).where(sql, { query: "%#{query.upcase}%" })
end
scope :search_with, ->(params) do
if params[:q].present?
if "yelp" == params[:source]
search_yelp(
q: params[:q],
categories: params[:categories],
city: params[:city],
page: (params[:page] || 1).to_i,
per_page: (params[:per_page] || 20).to_i
)
else
includes(:location).search(params[:q]).order(:name)
end
else
includes(:location).order(:name)
end
end
def self.search_yelp(q: "gym", categories: ["gyms"], city: , page: 1, per_page: 20)
Search.yelp.for(q, city, categories, page, per_page) do |result|
Gym.map_from(result)
end
end
def self.map_from(result)
Gym.new(
name: result.name,
yelp_id: result.id,
location_attributes: {
address: result.location.address.first,
city: result.location.city,
postal_code: result.location.postal_code,
region: result.location.state_code,
country: result.location.country_code,
latitude: result.location.coordinate.try(:latitude),
longitude: result.location.coordinate.try(:longitude),
}
)
end
def self.create_from_yelp!(id)
Gym.find_by(yelp_id: id) || Gym.map_from(Search.yelp.for_business(id))
end
def self.import(city, pages: 5)
return if city.blank?
return [] if Rails.env.test?
(1..pages).each do |page|
Gym.search_yelp(q: "gym", city: city, page: page).each(&:save!)
end
end
def map_url
params = [location.latitude, location.longitude, "12z"].join(",")
"https://maps.google.com/maps/place/#{name}/@#{params}"
end
def duplicate?(distance: 0.1)
return true if yelp_id.present? && Gym.where.not(id: id).exists?(yelp_id: yelp_id)
Gym.
closest_to(location, distance: distance).
where.not(id: id).
limit(1).
any?
end
end
|