Skip to content

Instantly share code, notes, and snippets.

@mwawrusch
Created August 22, 2011 12:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mwawrusch/1162302 to your computer and use it in GitHub Desktop.
Save mwawrusch/1162302 to your computer and use it in GitHub Desktop.
BigMess
# Owner (non embedded)
# Represents a single destination (can be country,...)
class Destination
include Mongoid::Document
include Mongoid::Timestamps
include Mongoid::Slug
include SimpleWorker::UsedInWorker
# Fields :::::::::::::::::::::::::::::::::::::::::::::
field :name
field :description
field :search_dc, :type => Array, :default => []
slug :name,:index => true, :permanent => true do
|destination| "#{destination.name}"
end
# Indexes :::::::::::::::::::::::::::::::::::::::::::
index :search_dc
# Relations :::::::::::::::::::::::::::::::::::::::::
embeds_one :location, :class_name => "DestinationLocation", #:validate => false, \
:inverse_of => :destination #, :default => NotificationSetting.new
# Methods :::::::::::::::::::::::::::::::::::::::::::
def location_latlong
[location.location[:lat],location.location[:lng] ]
end
# Callbacks ::::::::::::::::::::::::::::::::::::::::
# We are creating a downcased and stripped version of the name for search.
before_save do
new_name = self.name.downcase.strip
self.search_dc << new_name unless self.search_dc.include?(new_name)
# Included to fix existing fuck ups
if self.search_dc.length > 1
test = Hash[self.search_dc.map{|x| [x, x]}].values
self.search_dc = test if self.search_dc.length != test.length
end
end
# Searches for the tag case insensitive in the search collection
# returns nil if not found.
def self.find_by_search_dc(name)
Destination.where(:search_dc => name.downcase.strip).first rescue nil
end
end
# Embedded:
class Location
include Mongoid::Document
include SimpleWorker::UsedInWorker
include Mongoid::Spacial::Document
embeds_many :address_components, :class_name => "AddressComponent", #:validate => false, \
:inverse_of => :location #, :default => NotificationSetting.new
# The adress entred by a user.
field :entered_address
# True if this address has been resolved
field :address_resolved, :type => Boolean, :default => false
# long/lat format
field :location, :type => Array, spacial: true
#geo_index :location
field :location_type
field :types, :type => Array,:default => []
# additional stuff that we might determine through external api use
field :country
field :country_code
field :state
field :region
field :street
field :zip_code
field :yahoo_woeid, :type => Integer
field :yahoo_placetype
field :yahoo_placetype_code, :type => Integer
field :yahoo_uri
field :yahoo_pop_rank, :type => Integer
field :yahoo_area_rank, :type => Integer
field :bounding_box_min, :type => Array, spacial: true
field :bounding_box_max, :type => Array, spacial: true
field :viewport_min, :type => Array, spacial: true
field :viewport_max, :type => Array, spacial: true
end
class DestinationLocation < Location
include SimpleWorker::UsedInWorker
# Assocations :::::::::::::::::::::::::::::::::::::::::::::::::::::
embedded_in :destination , :inverse_of => :location
end
# Represents a location on this planet
class AddressComponent
include Mongoid::Document
include SimpleWorker::UsedInWorker
# The adress entred by a user.
field :name
# True if this address has been resolved
field :short_name
field :types, :type => Array,:default => []
# Assocations :::::::::::::::::::::::::::::::::::::::::::::::::::::
embedded_in :location , :inverse_of => :address_locations, polymorphic: true
def to_api
{
:name => self.name,
:shortName => self.short_name,
:types => self.types
}
end
end
### RAKE TASK
desc "update_destinations from google"
task :update_destinations => :environment do
Geocoder::Configuration.timeout = 20
Destination.all.each do |d|
puts "Processing #{d.name}"
r = Geocoder.search(d.name)
#puts r.inspect
if r && r.length > 0
d.location = nil
d.save!
puts "2"
geocoder_result = r[0]
formatted_address = geocoder_result.formatted_address
lat = geocoder_result.geometry["location"]["lat"]
lng = geocoder_result.geometry["location"]["lng"]
puts "3"
d.name = formatted_address
types = geocoder_result.types || []
location_type = geocoder_result.geometry["location_type"]
puts "4"
d.location = DestinationLocation.new(:address_resolved => true)
d.location.entered_address = formatted_address
d.location.location = [lng,lat] # long/lat
puts "5"
(geocoder_result.address_components || []).each do |x|
puts "5a #{x["long_name"]}"
ac = AddressComponent.new(:name => x["long_name"], :short_name => x["short_name"], :types => x["types"] || [])
puts "5b --> The next statement blows"
d.location.address_components << ac
puts "5x"
end
puts "6"
d.location.location_type = location_type
d.location.types = types
puts "7"
if geocoder_result.geometry["bounds"]
sw_lat = geocoder_result.geometry["bounds"]["southwest"]["lat"]
sw_lng = geocoder_result.geometry["bounds"]["southwest"]["lng"]
ne_lat = geocoder_result.geometry["bounds"]["northeast"]["lat"]
ne_lng = geocoder_result.geometry["bounds"]["northeast"]["lng"]
d.location.bounding_box_min = [sw_lng,sw_lat]
d.location.bounding_box_max = [ne_lng,ne_lat]
end
puts "8"
if geocoder_result.geometry["viewport"]
sw_lat = geocoder_result.geometry["viewport"]["southwest"]["lat"]
sw_lng = geocoder_result.geometry["viewport"]["southwest"]["lng"]
ne_lat = geocoder_result.geometry["viewport"]["northeast"]["lat"]
ne_lng = geocoder_result.geometry["viewport"]["northeast"]["lng"]
d.location.viewport_min = [sw_lng,sw_lat]
d.location.viewport_max = [ne_lng,ne_lat]
end
puts "9"
d.save!
puts "10"
end
return
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment