-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathmodels.rb
98 lines (72 loc) · 2.32 KB
/
models.rb
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
93
94
95
96
97
98
require 'data_mapper'
require 'graticule'
require 'bcrypt'
DataMapper.setup(:default, ENV['DATABASE_URL'])
class User
include DataMapper::Resource
property :id, Serial
property :name, String, { :required => true }
property :email, String, { :required => true,
:unique => true,
:format => :email_address }
property :password, BCryptHash
has n, :restaurants, { :child_key => [:creator_id] }
has n, :created_restrictions, "Restriction", { :child_key => [:creator_id] }
end
class Restaurant
SEARCH_RADIUS = 10
include DataMapper::Resource
property :id, Serial
property :name, String, { :required => true }
property :address, Text, { :required => true }
property :latitude, Float
property :longitude, Float
belongs_to :creator, 'User'
has n, :restaurants_restrictions
has n, :supported_restrictions, "Restriction", { :through => :restaurants_restrictions }
def add_supported_restriction(restriction)
self.restaurants_restrictions.first_or_create(:supported_restriction => restriction)
end
def self.search(query, options={})
restaurants = all(:name.like => "%#{query}%") |
all(supported_restrictions.name.like => "%#{query}%") |
all(:address.like => "%#{query}%")
return restaurants unless options[:near]
location = geocoder.locate(options[:near])
restaurants.select do |restaurant|
restaurant.near?(location)
end
end
def near?(other_location)
self.location.distance_to(other_location) <= SEARCH_RADIUS
end
def refresh_geolocation!
location = geocoder.locate(address)
self.latitude = location.latitude
self.longitude = location.longitude
self.save
end
def location
@location ||= Graticule::Location.new({ latitude: self.latitude, longitude: self.longitude })
end
def geocoder
self.class.geocoder
end
def self.geocoder
@@geocoder ||= Graticule.service(:google).new ENV['GOOGLE_GEOCODER_API_KEY']
end
end
class RestaurantsRestriction
include DataMapper::Resource
property :id, Serial
belongs_to :supported_restriction, "Restriction"
belongs_to :restaurant
end
class Restriction
include DataMapper::Resource
property :id, Serial
property :name, String, { :required => true }
belongs_to :creator, 'User'
end
DataMapper.finalize
DataMapper.auto_upgrade!