mirror of
https://github.com/Growstuff/growstuff.git
synced 2026-11-01 02:39:26 -05:00
- Introduced crop suggestions functionality allowing users to receive tailored crop recommendations based on their location and preferences. - Implemented the ability for users to dismiss specific crop suggestions, preventing them from receiving recommendations for crops they are not interested in. - Added a location picker for users to set their gardening location, enhancing the accuracy of crop suggestions. - Enhanced the dashboard to display relevant statistics, including plantings and harvests, with comparisons to previous years. - Created new views and partials for displaying statistics, crop suggestions, and user interactions on the dashboard. - Updated routes to accommodate new features related to crop suggestions and member locations. - Added migrations for new database tables and columns to support crop dismissal and suggestion preferences. - Developed tests for the new features, ensuring functionality and user experience are maintained.
47 lines
1.7 KiB
Ruby
47 lines
1.7 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
# Turns what someone typed, or where their browser says they are, into a short
|
|
# list of named places with coordinates for them to choose from.
|
|
#
|
|
# Used by the "tell us where you garden" dialog. Nominatim asks that clients
|
|
# do not search as someone types, so callers search on request, and results
|
|
# are cached so repeating a search costs nothing.
|
|
class PlaceSuggester
|
|
LIMIT = 6
|
|
|
|
def self.search(query)
|
|
query = query.to_s.squish.first(100)
|
|
return [] if query.length < 2
|
|
|
|
cached(['place-search', query.downcase]) { format(Geocoder.search(query, params: { limit: LIMIT, addressdetails: 1 })) }
|
|
end
|
|
|
|
def self.reverse(latitude, longitude)
|
|
cached(['place-reverse', latitude.round(2), longitude.round(2)]) do
|
|
format(Geocoder.search([latitude, longitude], params: { zoom: 10, addressdetails: 1 }))
|
|
end
|
|
end
|
|
|
|
def self.cached(key, &)
|
|
Rails.cache.fetch(key, expires_in: 1.day, skip_nil: true, &)
|
|
rescue Geocoder::Error, Timeout::Error, SocketError
|
|
[]
|
|
end
|
|
|
|
def self.format(results)
|
|
results.filter_map { |result| place(result) }.uniq { |place| place[:name] }.first(LIMIT)
|
|
end
|
|
|
|
# "Wellington, New Zealand": the place, the region when it differs, the country.
|
|
def self.place(result)
|
|
address = result.data['address']
|
|
address = {} unless address.is_a?(Hash)
|
|
name = result.data['name'].presence || address.values_at('city', 'town', 'village', 'suburb', 'county', 'state').compact.first
|
|
return if name.blank? || result.latitude.blank? || result.longitude.blank?
|
|
|
|
parts = [name, address['state'], address['country']].compact_blank.uniq
|
|
{ name: parts.join(', '), latitude: result.latitude.to_f, longitude: result.longitude.to_f }
|
|
end
|
|
private_class_method :place, :cached, :format
|
|
end
|