Module: ActsAsGeocodable
- Defined in:
- lib/acts_as_geocodable/version.rb,
lib/acts_as_geocodable/remote_location.rb,
lib/acts_as_geocodable.rb
Defined Under Namespace
Modules: Model, RemoteLocation
Constant Summary collapse
- VERSION =
"2.1.1"
Instance Method Summary collapse
-
#acts_as_geocodable(options = {}) ⇒ Object
Make a model geocodable.
Instance Method Details
#acts_as_geocodable(options = {}) ⇒ Object
Make a model geocodable.
class Event < ActiveRecord::Base
acts_as_geocodable
end
Options
-
:address
: A hash that maps geocodable attirbutes (:street
,:locality
,:region
,:postal_code
,:country
) to your model’s address fields, or a symbol to store the entire address in one field -
:normalize_address
: If set to true, you address fields will be updated using the address fields returned by the geocoder. (Default isfalse
) -
:units
: Default units-:miles
or:kilometers
-used for distance calculations and queries. (Default is:miles
)
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 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/acts_as_geocodable.rb', line 33 def acts_as_geocodable( = {}) = { address: { street: :street, locality: :locality, region: :region, postal_code: :postal_code, country: :country}, normalize_address: false, distance_column: "distance", units: :miles }.merge() class_attribute :acts_as_geocodable_options self. = define_callbacks :geocoding if ActiveRecord::VERSION::MAJOR >= 4 has_one :geocoding, -> { includes :geocode }, as: :geocodable, dependent: :destroy else has_one :geocoding, as: :geocodable, include: :geocode, dependent: :destroy end after_save :attach_geocode # Would love to do a simpler scope here, like: # scope :with_geocode_fields, includes(:geocoding) # But we need to use select() and it would get overwritten. scope :with_geocode_fields, lambda { joins("JOIN geocodings ON #{table_name}.#{primary_key} = geocodings.geocodable_id AND geocodings.geocodable_type = '#{model_name}' JOIN geocodes ON geocodings.geocode_id = geocodes.id") } # Use ActiveRecord ARel style syntax for finding records. # # Model.origin("Chicago, IL", within: 10) # # a +distance+ attribute indicating the distance # to the origin is added to each of the results: # # Model.origin("Portland, OR").first.distance #=> 388.383 # # == Options # # * <tt>origin</tt>: A Geocode, String, or geocodable model that specifies # the origin # * <tt>:within</tt>: Limit to results within this radius of the origin # * <tt>:beyond</tt>: Limit to results outside of this radius from the origin # * <tt>:units</tt>: Units to use for <tt>:within</tt> or <tt>:beyond</tt>. # Default is <tt>:miles</tt> unless specified otherwise in the +acts_as_geocodable+ # declaration. # scope :origin, lambda { |*args| origin = location_to_geocode(args[0]) = { units: [:units], }.merge(args[1] || {}) distance_sql = sql_for_distance(origin, [:units]) scope = with_geocode_fields.select("#{table_name}.*, #{distance_sql} AS #{[:distance_column]}") scope = scope.where("#{distance_sql} > #{[:beyond]}") if [:beyond] if [:within] scope = scope.where("(geocodes.latitude = :lat AND geocodes.longitude = :long) OR (#{distance_sql} <= #{[:within]})", { lat: origin.latitude, long: origin.longitude }) end scope } scope :near, -> { order("#{[:distance_column]} ASC") } scope :far, -> { order("#{[:distance_column]} DESC") } include ActsAsGeocodable::Model end |