Pr0d1r2-active_record_geocodable 1.0.0 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/VERSION +1 -0
- data/active_record_geocodable.gemspec +56 -0
- data/lib/active_record_geocodable/base.rb +23 -0
- data/lib/active_record_geocodable/model.rb +76 -0
- data/spec/active_record_geocodable_spec.rb +202 -11
- metadata +6 -2
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.0.3
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{active_record_geocodable}
|
8
|
+
s.version = "1.0.3"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Marcin Nowicki"]
|
12
|
+
s.date = %q{2009-09-23}
|
13
|
+
s.description = %q{Allow any active record model to be geocoded by geokit gem and contain geodata}
|
14
|
+
s.email = %q{pr0d1r2@ragnarson.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".gitignore",
|
22
|
+
"LICENSE",
|
23
|
+
"README.rdoc",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"active_record_geocodable.gemspec",
|
27
|
+
"lib/active_record_geocodable.rb",
|
28
|
+
"lib/active_record_geocodable/base.rb",
|
29
|
+
"lib/active_record_geocodable/model.rb",
|
30
|
+
"spec/active_record_geocodable_spec.rb",
|
31
|
+
"spec/spec_helper.rb"
|
32
|
+
]
|
33
|
+
s.has_rdoc = true
|
34
|
+
s.homepage = %q{http://github.com/Pr0d1r2/active_record_geocodable}
|
35
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
36
|
+
s.require_paths = ["lib"]
|
37
|
+
s.rubygems_version = %q{1.3.1}
|
38
|
+
s.summary = %q{ActiveRecord is_geocodable method}
|
39
|
+
s.test_files = [
|
40
|
+
"spec/active_record_geocodable_spec.rb",
|
41
|
+
"spec/spec_helper.rb"
|
42
|
+
]
|
43
|
+
|
44
|
+
if s.respond_to? :specification_version then
|
45
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
46
|
+
s.specification_version = 2
|
47
|
+
|
48
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
49
|
+
s.add_development_dependency(%q<rspec>, [">= 0"])
|
50
|
+
else
|
51
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
52
|
+
end
|
53
|
+
else
|
54
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module Geocodable
|
3
|
+
module Base
|
4
|
+
|
5
|
+
def is_geocodable(options = {})
|
6
|
+
include ActiveRecord::Geocodable::Model
|
7
|
+
options = {:geocode => true}.merge(options)
|
8
|
+
if options[:require]
|
9
|
+
validates_presence_of :lat
|
10
|
+
validates_presence_of :lng
|
11
|
+
validates_numericality_of :lat
|
12
|
+
validates_numericality_of :lng
|
13
|
+
options[:geocode] = true
|
14
|
+
end
|
15
|
+
before_validation :geocode_complete_address if options[:geocode]
|
16
|
+
named_scope :geocoded, :conditions => "#{table_name}.lat IS NOT NULL AND #{table_name}.lng IS NOT NULL"
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
ActiveRecord::Base.extend(ActiveRecord::Geocodable::Base)
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'geokit'
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
module Geocodable
|
5
|
+
module Model
|
6
|
+
|
7
|
+
def geo
|
8
|
+
@geo ||= geocoder.geocode(complete_address)
|
9
|
+
end
|
10
|
+
|
11
|
+
def geocoding_occured?
|
12
|
+
!@geo.nil?
|
13
|
+
end
|
14
|
+
|
15
|
+
def geocoding_successful?
|
16
|
+
geocoding_occured? && geo.success
|
17
|
+
end
|
18
|
+
|
19
|
+
def lat?
|
20
|
+
!lat.nil?
|
21
|
+
end
|
22
|
+
|
23
|
+
def lng?
|
24
|
+
!lng.nil?
|
25
|
+
end
|
26
|
+
|
27
|
+
def geocoded?
|
28
|
+
lat? && lng?
|
29
|
+
end
|
30
|
+
|
31
|
+
def geocoder
|
32
|
+
Geokit::Geocoders::MultiGeocoder
|
33
|
+
end
|
34
|
+
|
35
|
+
def geocode_complete_address
|
36
|
+
if geocode? && geocode_complete_address?
|
37
|
+
if runned_geocoding_successful?
|
38
|
+
set_geocode_data && true
|
39
|
+
else
|
40
|
+
geocode_complete_address_error
|
41
|
+
false
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def runned_geocoding_successful?
|
47
|
+
geo && geocoding_successful?
|
48
|
+
end
|
49
|
+
|
50
|
+
def set_geocode_data
|
51
|
+
!(self.lat = geo.lat).nil? && !(self.lng = geo.lng).nil?
|
52
|
+
end
|
53
|
+
|
54
|
+
def geocode_complete_address_error
|
55
|
+
errors.add(:complete_address, geocode_complete_address_error_messsage)
|
56
|
+
end
|
57
|
+
|
58
|
+
def geocode_complete_address_error_messsage
|
59
|
+
"Cannot geocode complete address: #{complete_address}"
|
60
|
+
end
|
61
|
+
|
62
|
+
def geocode_complete_address?
|
63
|
+
complete_address_changed? && complete_address?
|
64
|
+
end
|
65
|
+
|
66
|
+
def complete_address?
|
67
|
+
!complete_address.blank?
|
68
|
+
end
|
69
|
+
|
70
|
+
def geocode?
|
71
|
+
true
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -2,38 +2,75 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
2
2
|
require 'active_record_connectionless'
|
3
3
|
|
4
4
|
class GeocodableModel < ActiveRecord::Base
|
5
|
+
emulate_attribute :lat, :lng
|
5
6
|
is_geocodable
|
6
7
|
end
|
7
8
|
|
9
|
+
class GeocodableModelWithoutGeocode < ActiveRecord::Base
|
10
|
+
emulate_attribute :lat, :lng
|
11
|
+
is_geocodable :geocode => false
|
12
|
+
end
|
13
|
+
|
14
|
+
class GeocodableModelWithRequire < ActiveRecord::Base
|
15
|
+
emulate_attribute :lat, :lng
|
16
|
+
is_geocodable :require => true
|
17
|
+
end
|
18
|
+
|
8
19
|
|
9
20
|
describe GeocodableModel do
|
10
21
|
|
11
22
|
before(:each) do
|
12
23
|
@geocodable_model = GeocodableModel.new
|
24
|
+
@geocoder = mock(Geokit::Geocoders::MultiGeocoder)
|
25
|
+
@geo = mock(Geokit::GeoLoc)
|
13
26
|
end
|
14
27
|
|
15
|
-
it 'geo should return geocoded
|
16
|
-
@
|
17
|
-
|
28
|
+
it 'geo should return geocoded complete_address from multigeocoder' do
|
29
|
+
@geocoder.should_receive(:geocode).with(:complete_address).and_return(:geo)
|
30
|
+
@geocodable_model.should_receive(:geocoder).and_return(@geocoder)
|
31
|
+
@geocodable_model.should_receive(:complete_address).and_return(:complete_address)
|
18
32
|
@geocodable_model.geo.should == :geo
|
19
33
|
end
|
20
34
|
|
21
35
|
describe 'geocoding_occured?' do
|
22
36
|
it 'should be true when geocoding occured' do
|
23
|
-
|
24
|
-
@geocodable_model.
|
37
|
+
@geocoder.should_receive(:geocode).and_return(:geo)
|
38
|
+
@geocodable_model.should_receive(:geocoder).and_return(@geocoder)
|
39
|
+
@geocodable_model.stub!(:complete_address)
|
25
40
|
@geocodable_model.geo
|
26
41
|
@geocodable_model.geocoding_occured?.should be_true
|
27
42
|
end
|
28
43
|
|
29
44
|
it 'should be false when geocoding not occured' do
|
30
|
-
|
31
|
-
@geocodable_model.
|
45
|
+
@geocoder.should_receive(:geocode).and_return(nil)
|
46
|
+
@geocodable_model.should_receive(:geocoder).and_return(@geocoder)
|
47
|
+
@geocodable_model.stub!(:complete_address)
|
32
48
|
@geocodable_model.geo
|
33
49
|
@geocodable_model.geocoding_occured?.should be_false
|
34
50
|
end
|
35
51
|
end
|
36
52
|
|
53
|
+
describe 'geocoding_successful?' do
|
54
|
+
it 'should be true when geocoding occured and was successful' do
|
55
|
+
@geocodable_model.should_receive(:geocoding_occured?).and_return(true)
|
56
|
+
@geocodable_model.should_receive(:geo).and_return(@geo)
|
57
|
+
@geo.should_receive(:success).and_return(true)
|
58
|
+
@geocodable_model.geocoding_successful?.should be_true
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should be false when geocoding not occured' do
|
62
|
+
@geocodable_model.should_receive(:geocoding_occured?).and_return(false)
|
63
|
+
@geocodable_model.geocoding_successful?.should be_false
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should be false when geocoding occured but was not successful' do
|
67
|
+
@geocodable_model.should_receive(:geocoding_occured?).and_return(true)
|
68
|
+
@geocodable_model.should_receive(:geo).and_return(@geo)
|
69
|
+
@geo.should_receive(:success).and_return(false)
|
70
|
+
@geocodable_model.geocoding_successful?.should be_false
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
37
74
|
describe 'lat?' do
|
38
75
|
it 'should be true when lat is not nil' do
|
39
76
|
@geocodable_model.should_receive(:lat).and_return(47)
|
@@ -58,23 +95,177 @@ describe GeocodableModel do
|
|
58
95
|
end
|
59
96
|
end
|
60
97
|
|
61
|
-
describe '
|
98
|
+
describe 'geocoded?' do
|
62
99
|
it 'should be true when lat and lng are ok' do
|
63
100
|
@geocodable_model.should_receive(:lat?).and_return(true)
|
64
101
|
@geocodable_model.should_receive(:lng?).and_return(true)
|
65
|
-
@geocodable_model.
|
102
|
+
@geocodable_model.geocoded?.should be_true
|
66
103
|
end
|
67
104
|
|
68
105
|
it 'should be false when lng is not ok' do
|
69
106
|
@geocodable_model.should_receive(:lat?).and_return(true)
|
70
107
|
@geocodable_model.should_receive(:lng?).and_return(false)
|
71
|
-
@geocodable_model.
|
108
|
+
@geocodable_model.geocoded?.should be_false
|
72
109
|
end
|
73
110
|
|
74
111
|
it 'should be false when lat is not ok' do
|
75
112
|
@geocodable_model.should_receive(:lat?).and_return(false)
|
76
|
-
@geocodable_model.
|
113
|
+
@geocodable_model.geocoded?.should be_false
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'geocoder should return Geokit::Geocoders::MultiGeocoder' do
|
118
|
+
@geocodable_model.geocoder.should == Geokit::Geocoders::MultiGeocoder
|
119
|
+
end
|
120
|
+
|
121
|
+
describe 'geocode_complete_address' do
|
122
|
+
it 'should do nothing when we prevent geocoding' do
|
123
|
+
@geocodable_model.should_receive(:geocode?).and_return(false)
|
124
|
+
@geocodable_model.geocode_complete_address.should be_nil
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'should do nothing when complete address not ready for geocoding' do
|
128
|
+
@geocodable_model.should_receive(:geocode?).and_return(true)
|
129
|
+
@geocodable_model.should_receive(:geocode_complete_address?).and_return(false)
|
130
|
+
@geocodable_model.geocode_complete_address.should be_nil
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'should set_geocode_data when geocoding was successful' do
|
134
|
+
@geocodable_model.should_receive(:geocode?).and_return(true)
|
135
|
+
@geocodable_model.should_receive(:geocode_complete_address?).and_return(true)
|
136
|
+
@geocodable_model.should_receive(:runned_geocoding_successful?).and_return(true)
|
137
|
+
@geocodable_model.should_receive(:set_geocode_data).and_return(true)
|
138
|
+
@geocodable_model.geocode_complete_address.should be_true
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'should set error for complete address when geocoding was not successful' do
|
142
|
+
@geocodable_model.should_receive(:geocode?).and_return(true)
|
143
|
+
@geocodable_model.should_receive(:geocode_complete_address?).and_return(true)
|
144
|
+
@geocodable_model.should_receive(:runned_geocoding_successful?).and_return(false)
|
145
|
+
@geocodable_model.should_receive(:geocode_complete_address_error)
|
146
|
+
@geocodable_model.geocode_complete_address.should be_false
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
describe 'set_geocode_data' do
|
151
|
+
it 'should set data from geo and return true' do
|
152
|
+
@geo.should_receive(:lat).and_return(84)
|
153
|
+
@geo.should_receive(:lng).and_return(72)
|
154
|
+
@geocodable_model.should_receive(:geo).twice.and_return(@geo)
|
155
|
+
@geocodable_model.set_geocode_data.should be_true
|
156
|
+
@geocodable_model.lat.should == 84
|
157
|
+
@geocodable_model.lng.should == 72
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'should return false when not both lat and lng was set' do
|
161
|
+
@geo.should_receive(:lat).and_return(84)
|
162
|
+
@geo.should_receive(:lng).and_return(nil)
|
163
|
+
@geocodable_model.should_receive(:geo).twice.and_return(@geo)
|
164
|
+
@geocodable_model.set_geocode_data.should be_false
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
it 'geocode_complete_address_error should add error to complete_address' do
|
169
|
+
@geocodable_model.should_receive(:geocode_complete_address_error_messsage).and_return(:geocode_complete_address_error_messsage)
|
170
|
+
errors = mock(ActiveRecord::Errors)
|
171
|
+
errors.should_receive(:add).with(:complete_address, :geocode_complete_address_error_messsage)
|
172
|
+
@geocodable_model.should_receive(:errors).and_return(errors)
|
173
|
+
@geocodable_model.geocode_complete_address_error
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'geocode_complete_address_error_messsage should have proper message' do
|
177
|
+
@geocodable_model.should_receive(:complete_address).and_return('complete_address')
|
178
|
+
@geocodable_model.geocode_complete_address_error_messsage.should == "Cannot geocode complete address: complete_address"
|
179
|
+
end
|
180
|
+
|
181
|
+
describe 'geocode_complete_address?' do
|
182
|
+
it 'should be true when complete_address changed and it is not blank' do
|
183
|
+
@geocodable_model.should_receive(:complete_address_changed?).and_return(true)
|
184
|
+
@geocodable_model.should_receive(:complete_address?).and_return(true)
|
185
|
+
@geocodable_model.geocode_complete_address?.should be_true
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'should be false when complete_address changed but it is blank' do
|
189
|
+
@geocodable_model.should_receive(:complete_address_changed?).and_return(true)
|
190
|
+
@geocodable_model.should_receive(:complete_address?).and_return(false)
|
191
|
+
@geocodable_model.geocode_complete_address?.should be_false
|
77
192
|
end
|
193
|
+
|
194
|
+
it 'should be false when complete_address not changed' do
|
195
|
+
@geocodable_model.should_receive(:complete_address_changed?).and_return(false)
|
196
|
+
@geocodable_model.geocode_complete_address?.should be_false
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
describe 'complete_address?' do
|
201
|
+
it 'should be true when complete_address is not blank' do
|
202
|
+
@geocodable_model.should_receive(:complete_address).and_return('complete address')
|
203
|
+
@geocodable_model.complete_address?.should be_true
|
204
|
+
end
|
205
|
+
|
206
|
+
it 'should be false when complete_address is blank' do
|
207
|
+
@geocodable_model.should_receive(:complete_address).and_return('')
|
208
|
+
@geocodable_model.complete_address?.should be_false
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
it 'geocode? should be true unless You want to disable geocoding' do
|
213
|
+
@geocodable_model.geocode?.should be_true
|
214
|
+
end
|
215
|
+
|
216
|
+
it 'should validate geocode_complete_address' do
|
217
|
+
@geocodable_model.should_receive(:geocode_complete_address).and_return(true)
|
218
|
+
@geocodable_model.should be_valid
|
219
|
+
end
|
220
|
+
|
221
|
+
it 'should provide geocoded named_scope' do
|
222
|
+
GeocodableModel.should_receive(:find).and_return([])
|
223
|
+
GeocodableModel.geocoded.should == []
|
224
|
+
end
|
225
|
+
|
226
|
+
end
|
227
|
+
|
228
|
+
|
229
|
+
describe GeocodableModelWithoutGeocode do
|
230
|
+
|
231
|
+
it 'should not validate geocode_complete_address' do
|
232
|
+
geocodable_model = GeocodableModelWithoutGeocode.new
|
233
|
+
geocodable_model.should_not_receive(:geocode_complete_address)
|
234
|
+
geocodable_model.should be_valid
|
235
|
+
end
|
236
|
+
|
237
|
+
end
|
238
|
+
|
239
|
+
|
240
|
+
describe GeocodableModelWithRequire do
|
241
|
+
|
242
|
+
before(:each) do
|
243
|
+
@geocodable_model = GeocodableModelWithRequire.new(:lat => 84, :lng => 72)
|
244
|
+
@geocodable_model.should_receive(:geocode_complete_address).and_return(true)
|
245
|
+
end
|
246
|
+
|
247
|
+
it 'should be valid with all ok' do
|
248
|
+
@geocodable_model.should be_valid
|
249
|
+
end
|
250
|
+
|
251
|
+
it 'should not be valid with empty lat' do
|
252
|
+
@geocodable_model.lat = nil
|
253
|
+
@geocodable_model.should_not be_valid
|
254
|
+
end
|
255
|
+
|
256
|
+
it 'should not be valid with empty lng' do
|
257
|
+
@geocodable_model.lng = nil
|
258
|
+
@geocodable_model.should_not be_valid
|
259
|
+
end
|
260
|
+
|
261
|
+
it 'should not be valid with not numeric lat' do
|
262
|
+
@geocodable_model.lat = 'a'
|
263
|
+
@geocodable_model.should_not be_valid
|
264
|
+
end
|
265
|
+
|
266
|
+
it 'should not be valid with not numeric lng' do
|
267
|
+
@geocodable_model.lng = 'a'
|
268
|
+
@geocodable_model.should_not be_valid
|
78
269
|
end
|
79
270
|
|
80
271
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: Pr0d1r2-active_record_geocodable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marcin Nowicki
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-09-
|
12
|
+
date: 2009-09-23 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -37,7 +37,11 @@ files:
|
|
37
37
|
- LICENSE
|
38
38
|
- README.rdoc
|
39
39
|
- Rakefile
|
40
|
+
- VERSION
|
41
|
+
- active_record_geocodable.gemspec
|
40
42
|
- lib/active_record_geocodable.rb
|
43
|
+
- lib/active_record_geocodable/base.rb
|
44
|
+
- lib/active_record_geocodable/model.rb
|
41
45
|
- spec/active_record_geocodable_spec.rb
|
42
46
|
- spec/spec_helper.rb
|
43
47
|
has_rdoc: true
|