activerecord-spatial 1.0.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1670 -0
  3. data/Gemfile +12 -13
  4. data/Guardfile +7 -10
  5. data/MIT-LICENSE +1 -1
  6. data/README.rdoc +8 -19
  7. data/Rakefile +2 -1
  8. data/activerecord-spatial.gemspec +12 -13
  9. data/lib/activerecord-spatial/active_record/connection_adapters/postgresql/adapter_extensions/active_record.rb +46 -0
  10. data/lib/activerecord-spatial/active_record/connection_adapters/postgresql/adapter_extensions.rb +7 -38
  11. data/lib/activerecord-spatial/active_record/connection_adapters/postgresql/postgis.rb +6 -7
  12. data/lib/activerecord-spatial/active_record/connection_adapters/postgresql/unknown_srid.rb +4 -5
  13. data/lib/activerecord-spatial/active_record/models/geography_column.rb +1 -2
  14. data/lib/activerecord-spatial/active_record/models/geometry_column.rb +1 -2
  15. data/lib/activerecord-spatial/active_record/models/spatial_column.rb +1 -2
  16. data/lib/activerecord-spatial/active_record/models/spatial_ref_sys.rb +5 -6
  17. data/lib/activerecord-spatial/active_record.rb +0 -1
  18. data/lib/activerecord-spatial/associations/active_record.rb +62 -120
  19. data/lib/activerecord-spatial/associations/base.rb +26 -75
  20. data/lib/activerecord-spatial/associations/preloader/spatial_association.rb +57 -0
  21. data/lib/activerecord-spatial/associations/reflection/spatial_reflection.rb +41 -0
  22. data/lib/activerecord-spatial/associations.rb +26 -4
  23. data/lib/activerecord-spatial/spatial_columns.rb +85 -94
  24. data/lib/activerecord-spatial/spatial_function.rb +62 -51
  25. data/lib/activerecord-spatial/spatial_scope_constants/postgis_2_0.rb +48 -0
  26. data/lib/activerecord-spatial/spatial_scope_constants/postgis_2_2.rb +46 -0
  27. data/lib/activerecord-spatial/spatial_scope_constants/postgis_legacy.rb +30 -0
  28. data/lib/activerecord-spatial/spatial_scope_constants.rb +10 -61
  29. data/lib/activerecord-spatial/spatial_scopes.rb +47 -49
  30. data/lib/activerecord-spatial/version.rb +1 -2
  31. data/lib/activerecord-spatial.rb +2 -6
  32. data/lib/tasks/test.rake +21 -19
  33. data/test/.rubocop.yml +35 -0
  34. data/test/accessors_geographies_tests.rb +19 -19
  35. data/test/accessors_geometries_tests.rb +19 -19
  36. data/test/adapter_tests.rb +1 -2
  37. data/test/associations_tests.rb +181 -203
  38. data/test/geography_column_tests.rb +2 -3
  39. data/test/geometry_column_tests.rb +1 -2
  40. data/test/models/bar.rb +2 -3
  41. data/test/models/blort.rb +1 -2
  42. data/test/models/foo.rb +2 -3
  43. data/test/models/foo3d.rb +2 -3
  44. data/test/models/foo_geography.rb +2 -3
  45. data/test/models/zortable.rb +2 -3
  46. data/test/spatial_function_tests.rb +12 -17
  47. data/test/spatial_scopes_geographies_tests.rb +17 -20
  48. data/test/spatial_scopes_tests.rb +84 -75
  49. data/test/test_helper.rb +66 -79
  50. metadata +16 -14
  51. data/lib/activerecord-spatial/associations/active_record_3.rb +0 -123
data/test/test_helper.rb CHANGED
@@ -4,16 +4,19 @@ require 'simplecov'
4
4
  SimpleCov.command_name('Unit Tests')
5
5
  SimpleCov.start do
6
6
  add_filter '/test/'
7
+ add_filter '/.bundle/'
7
8
  end
8
9
 
9
10
  require 'rubygems'
10
11
  require 'minitest/autorun'
11
12
  require 'minitest/reporters'
13
+ require 'rails'
12
14
  require 'active_support'
13
15
  require 'active_support/core_ext/module/aliasing'
14
16
  require 'active_support/dependencies'
15
17
  require 'active_record'
16
18
  require 'active_record/fixtures'
19
+ require 'active_record/test_case'
17
20
  require 'logger'
18
21
 
19
22
  require File.join(File.dirname(__FILE__), %w{ .. lib activerecord-spatial })
@@ -22,11 +25,11 @@ POSTGIS_PATHS = [
22
25
  ENV['POSTGIS_PATH'],
23
26
  '/opt/local/share/postgresql*/contrib/postgis-*',
24
27
  '/usr/share/postgresql*/contrib/postgis-*',
25
- '/usr/pgsql-*/share/contrib/postgis-*',
28
+ '/usr/pgsql-*/share/contrib/postgis-*'
26
29
  ].compact
27
30
 
28
31
  puts "ActiveRecordSpatial #{ActiveRecordSpatial::VERSION}"
29
- puts "ActiveRecord #{Gem.loaded_specs['activerecord'].version.to_s}"
32
+ puts "ActiveRecord #{Gem.loaded_specs['activerecord'].version}"
30
33
  puts "Ruby #{RUBY_VERSION}-p#{RUBY_PATCHLEVEL} - #{RbConfig::CONFIG['RUBY_INSTALL_NAME']}"
31
34
  puts "Geos library #{Geos::VERSION}" if defined?(Geos::VERSION)
32
35
  puts "GEOS #{Geos::GEOS_VERSION}"
@@ -35,7 +38,8 @@ if defined?(Geos::FFIGeos)
35
38
  puts "Using #{Geos::FFIGeos.geos_library_paths.join(', ')}"
36
39
  end
37
40
 
38
- ActiveRecord::Base.logger = Logger.new("debug.log") if ENV['ENABLE_LOGGER']
41
+ ActiveSupport::TestCase.test_order = :random
42
+ ActiveRecord::Base.logger = Logger.new('debug.log') if ENV['ENABLE_LOGGER']
39
43
  ActiveRecord::Base.configurations = {
40
44
  'arunit' => {}
41
45
  }
@@ -46,9 +50,9 @@ ActiveRecord::Base.configurations = {
46
50
  }.each do |file|
47
51
  file = File.join('test', file)
48
52
 
49
- next unless File.exists?(file)
53
+ next unless File.exist?(file)
50
54
 
51
- configuration = YAML.load(File.read(file))
55
+ configuration = YAML.safe_load(File.read(file))
52
56
 
53
57
  if configuration['arunit']
54
58
  ActiveRecord::Base.configurations['arunit'].merge!(configuration['arunit'])
@@ -59,17 +63,21 @@ ActiveRecord::Base.configurations = {
59
63
  end
60
64
  end
61
65
 
62
- ActiveRecord::Base.establish_connection 'arunit'
66
+ ActiveRecord::Base.establish_connection :arunit
63
67
  ARBC = ActiveRecord::Base.connection
64
68
 
65
- if postgresql_version = ARBC.select_rows('SELECT version()').first.first
69
+ postgresql_version = ARBC.select_rows('SELECT version()').first.first
70
+
71
+ if postgresql_version.present?
66
72
  puts "PostgreSQL info from version(): #{postgresql_version}"
67
73
  end
68
74
 
69
- puts "Checking for PostGIS install"
75
+ puts 'Checking for PostGIS install'
70
76
  2.times do
71
77
  begin
72
- if postgis_version = ActiveRecordSpatial::POSTGIS[:lib]
78
+ postgis_version = ActiveRecordSpatial::POSTGIS[:lib]
79
+
80
+ if postgis_version.present?
73
81
  puts "PostGIS info from postgis_full_version(): #{postgis_version}"
74
82
  break
75
83
  end
@@ -77,9 +85,7 @@ puts "Checking for PostGIS install"
77
85
  puts "Trying to install PostGIS. If this doesn't work, you'll have to do this manually!"
78
86
 
79
87
  plpgsql = ARBC.select_rows(%{SELECT count(*) FROM pg_language WHERE lanname = 'plpgsql'}).first.first.to_i
80
- if plpgsql == 0
81
- ARBC.execute(%{CREATE LANGUAGE plpgsql})
82
- end
88
+ ARBC.execute(%{CREATE LANGUAGE plpgsql}) if plpgsql.zero?
83
89
 
84
90
  %w{
85
91
  postgis.sql
@@ -105,35 +111,39 @@ class ActiveRecordSpatialTestCase < ActiveRecord::TestCase
105
111
 
106
112
  REGEXP_WKB_HEX = /[A-Fa-f0-9\s]+/
107
113
 
108
- POINT_WKT = 'POINT(10 10.01)'
109
- POINT_EWKT = 'SRID=4326; POINT(10 10.01)'
110
- POINT_EWKT_WITH_DEFAULT = 'SRID=default; POINT(10 10.01)'
111
- POINT_WKB = "0101000000000000000000244085EB51B81E052440"
112
- POINT_WKB_BIN = "\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x24\x40\x85\xEB\x51\xB8\x1E\x05\x24\x40"
113
- POINT_EWKB = "0101000020E6100000000000000000244085EB51B81E052440"
114
- POINT_EWKB_BIN = "\x01\x01\x00\x00\x20\xE6\x10\x00\x00\x00\x00\x00\x00\x00\x00\x24\x40\x85\xEB\x51\xB8\x1E\x05\x24\x40"
115
- POINT_G_LAT_LNG = "(10.01, 10)"
116
- POINT_G_LAT_LNG_URL_VALUE = "10.01,10"
117
-
118
- POLYGON_WKT = 'POLYGON((0 0, 1 1, 2.5 2.5, 5 5, 0 0))'
119
- POLYGON_EWKT = 'SRID=4326; POLYGON((0 0, 1 1, 2.5 2.5, 5 5, 0 0))'
120
- POLYGON_WKB = "
114
+ POINT_WKT = 'POINT(10 10.01)'.freeze
115
+ POINT_EWKT = 'SRID=4326; POINT(10 10.01)'.freeze
116
+ POINT_EWKT_WITH_DEFAULT = 'SRID=default; POINT(10 10.01)'.freeze
117
+ POINT_WKB = '0101000000000000000000244085EB51B81E052440'.freeze
118
+ POINT_WKB_BIN = "\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x24\x40\x85\xEB\x51\xB8\x1E\x05\x24\x40".freeze
119
+ POINT_EWKB = '0101000020E6100000000000000000244085EB51B81E052440'.freeze
120
+ POINT_EWKB_BIN = "\x01\x01\x00\x00\x20\xE6\x10\x00\x00\x00\x00\x00\x00\x00\x00\x24\x40\x85\xEB\x51\xB8\x1E\x05\x24\x40".freeze
121
+ POINT_G_LAT_LNG = '(10.01, 10)'.freeze
122
+ POINT_G_LAT_LNG_URL_VALUE = '10.01,10'.freeze
123
+
124
+ POLYGON_WKT = 'POLYGON((0 0, 1 1, 2.5 2.5, 5 5, 0 0))'.freeze
125
+ POLYGON_EWKT = 'SRID=4326; POLYGON((0 0, 1 1, 2.5 2.5, 5 5, 0 0))'.freeze
126
+
127
+ POLYGON_WKB = '
121
128
  0103000000010000000500000000000000000000000000000000000000000000000000F
122
129
  03F000000000000F03F0000000000000440000000000000044000000000000014400000
123
130
  00000000144000000000000000000000000000000000
124
- ".gsub(/\s/, '')
131
+ '.gsub(/\s/, '').freeze
132
+
125
133
  POLYGON_WKB_BIN = [
126
134
  "\x01\x03\x00\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00",
127
135
  "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xF0\x3F\x00",
128
136
  "\x00\x00\x00\x00\x00\xF0\x3F\x00\x00\x00\x00\x00\x00\x04\x40\x00\x00\x00\x00",
129
137
  "\x00\x00\x04\x40\x00\x00\x00\x00\x00\x00\x14\x40\x00\x00\x00\x00\x00\x00\x14",
130
138
  "\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
131
- ].join
132
- POLYGON_EWKB = "
139
+ ].join.freeze
140
+
141
+ POLYGON_EWKB = '
133
142
  0103000020E610000001000000050000000000000000000000000000000000000000000
134
143
  0000000F03F000000000000F03F00000000000004400000000000000440000000000000
135
144
  1440000000000000144000000000000000000000000000000000
136
- ".gsub(/\s/, '')
145
+ '.gsub(/\s/, '').freeze
146
+
137
147
  POLYGON_EWKB_BIN = [
138
148
  "\x01\x03\x00\x00\x20\xE6\x10\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00",
139
149
  "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
@@ -141,11 +151,11 @@ class ActiveRecordSpatialTestCase < ActiveRecord::TestCase
141
151
  "\x00\x00\x00\x00\x04\x40\x00\x00\x00\x00\x00\x00\x04\x40\x00\x00\x00",
142
152
  "\x00\x00\x00\x14\x40\x00\x00\x00\x00\x00\x00\x14\x40\x00\x00\x00\x00",
143
153
  "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
144
- ].join
154
+ ].join.freeze
145
155
 
146
- POLYGON_WITH_INTERIOR_RING = "POLYGON((0 0, 5 0, 5 5, 0 5, 0 0),(4 4, 4 1, 1 1, 1 4, 4 4))"
156
+ POLYGON_WITH_INTERIOR_RING = 'POLYGON((0 0, 5 0, 5 5, 0 5, 0 0),(4 4, 4 1, 1 1, 1 4, 4 4))'.freeze
147
157
 
148
- LINESTRING_WKT = "LINESTRING (0 0, 5 5, 5 10, 10 10)"
158
+ LINESTRING_WKT = 'LINESTRING (0 0, 5 5, 5 10, 10 10)'.freeze
149
159
 
150
160
  GEOMETRYCOLLECTION_WKT = 'GEOMETRYCOLLECTION (
151
161
  MULTIPOLYGON (
@@ -161,20 +171,23 @@ class ActiveRecordSpatialTestCase < ActiveRecord::TestCase
161
171
  LINESTRING (0 0, 2 3),
162
172
  MULTIPOINT ((0 0), (2 3)),
163
173
  POINT (9 0)
164
- )'
174
+ )'.freeze
165
175
 
166
- BOUNDS_G_LAT_LNG = "((0.1, 0.1), (5.2, 5.2))"
167
- BOUNDS_G_LAT_LNG_URL_VALUE = '0.1,0.1,5.2,5.2'
176
+ BOUNDS_G_LAT_LNG = '((0.1, 0.1), (5.2, 5.2))'.freeze
177
+ BOUNDS_G_LAT_LNG_URL_VALUE = '0.1,0.1,5.2,5.2'.freeze
168
178
 
169
179
  class << self
170
180
  def load_models(*args)
171
- options = args.extract_options!
181
+ self.fixture_table_names = args.collect do |arg|
182
+ arg.to_s.pluralize
183
+ end
172
184
 
173
185
  args.each do |model|
174
186
  model = model.to_s
175
187
  klass = model.classify
188
+ fixtures model.tableize
176
189
 
177
- ActiveSupport::Dependencies.load_file(BASE_PATH.join("models/#{model}.rb"), [ klass ])
190
+ ActiveSupport::Dependencies.load_file(BASE_PATH.join("models/#{model}.rb"), [klass])
178
191
  end
179
192
  end
180
193
 
@@ -195,12 +208,16 @@ class ActiveRecordSpatialTestCase < ActiveRecord::TestCase
195
208
  def after_suite
196
209
  ActiveSupport::Dependencies.clear
197
210
  end
211
+
212
+ def table_exists?(table)
213
+ ARBC.data_source_exists?(table)
214
+ end
198
215
  end
199
216
 
200
217
  def setup
201
- if ActiveRecord::Base.logger
202
- ActiveRecord::Base.logger.debug("Beginning tests for #{self.class.name}##{self.method_name}")
203
- end
218
+ return unless ActiveRecord::Base.logger
219
+
220
+ ActiveRecord::Base.logger.debug("Beginning tests for #{self.class.name}##{method_name}")
204
221
  end
205
222
 
206
223
  def assert_saneness_of_point(point)
@@ -213,49 +230,20 @@ class ActiveRecordSpatialTestCase < ActiveRecord::TestCase
213
230
  assert_kind_of(Geos::Polygon, polygon)
214
231
  cs = polygon.exterior_ring.coord_seq
215
232
  assert_equal([
216
- [ 0, 0 ],
217
- [ 1, 1 ],
218
- [ 2.5, 2.5 ],
219
- [ 5, 5 ],
220
- [ 0, 0 ]
233
+ [0, 0],
234
+ [1, 1],
235
+ [2.5, 2.5],
236
+ [5, 5],
237
+ [0, 0]
221
238
  ], cs.to_a)
222
239
  end
223
- end
224
-
225
- if !defined?(ActiveRecord::SQLCounter)
226
- module ActiveRecord
227
- class SQLCounter
228
- cattr_accessor :ignored_sql
229
- self.ignored_sql = [
230
- /^PRAGMA (?!(table_info))/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/,
231
- /^SELECT @@ROWCOUNT/, /^SAVEPOINT/, /^ROLLBACK TO SAVEPOINT/, /^RELEASE SAVEPOINT/,
232
- /^SHOW max_identifier_length/, /^BEGIN/, /^COMMIT/, /^ROLLBACK/, /\WFROM pg_/
233
- ]
234
-
235
- cattr_accessor :log
236
- self.log = []
237
-
238
- attr_reader :ignore
239
-
240
- def initialize(ignore = self.class.ignored_sql)
241
- @ignore = ignore
242
- end
243
-
244
- def call(name, start, finish, message_id, values)
245
- sql = values[:sql]
246
-
247
- # FIXME: this seems bad. we should probably have a better way to indicate
248
- # the query was cached
249
- return if 'CACHE' == values[:name] || ignore.any? { |x| x =~ sql }
250
- self.class.log << sql
251
- end
252
- end
253
240
 
254
- ActiveSupport::Notifications.subscribe('sql.active_record', SQLCounter.new)
241
+ def reflection_key(key)
242
+ key.to_s
255
243
  end
256
244
  end
257
245
 
258
- class SpatialTestRunner < MiniTest::Reporters::SpecReporter
246
+ class SpatialTestRunner < Minitest::Reporters::SpecReporter
259
247
  def before_suite(suite)
260
248
  super(suite)
261
249
  suite.before_suite if suite.respond_to?(:before_suite)
@@ -267,5 +255,4 @@ class SpatialTestRunner < MiniTest::Reporters::SpecReporter
267
255
  end
268
256
  end
269
257
 
270
- MiniTest::Reporters.use!(SpatialTestRunner.new)
271
-
258
+ Minitest::Reporters.use!(SpatialTestRunner.new)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-spatial
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - J Smith
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-01 00:00:00.000000000 Z
11
+ date: 2017-03-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -16,34 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '3.2'
20
- - - "!="
21
- - !ruby/object:Gem::Version
22
- version: 4.0.0
19
+ version: '5.0'
23
20
  type: :runtime
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
26
23
  requirements:
27
24
  - - ">="
28
25
  - !ruby/object:Gem::Version
29
- version: '3.2'
30
- - - "!="
31
- - !ruby/object:Gem::Version
32
- version: 4.0.0
26
+ version: '5.0'
33
27
  - !ruby/object:Gem::Dependency
34
28
  name: geos-extensions
35
29
  requirement: !ruby/object:Gem::Requirement
36
30
  requirements:
37
31
  - - ">="
38
32
  - !ruby/object:Gem::Version
39
- version: 0.3.0.dev
33
+ version: '0.5'
40
34
  type: :runtime
41
35
  prerelease: false
42
36
  version_requirements: !ruby/object:Gem::Requirement
43
37
  requirements:
44
38
  - - ">="
45
39
  - !ruby/object:Gem::Version
46
- version: 0.3.0.dev
40
+ version: '0.5'
47
41
  description: ActiveRecord Spatial gives AR the ability to work with PostGIS columns.
48
42
  email: dark.panda@gmail.com
49
43
  executables: []
@@ -52,6 +46,7 @@ extra_rdoc_files:
52
46
  - README.rdoc
53
47
  files:
54
48
  - ".gitignore"
49
+ - ".rubocop.yml"
55
50
  - Gemfile
56
51
  - Guardfile
57
52
  - MIT-LICENSE
@@ -61,6 +56,7 @@ files:
61
56
  - lib/activerecord-spatial.rb
62
57
  - lib/activerecord-spatial/active_record.rb
63
58
  - lib/activerecord-spatial/active_record/connection_adapters/postgresql/adapter_extensions.rb
59
+ - lib/activerecord-spatial/active_record/connection_adapters/postgresql/adapter_extensions/active_record.rb
64
60
  - lib/activerecord-spatial/active_record/connection_adapters/postgresql/postgis.rb
65
61
  - lib/activerecord-spatial/active_record/connection_adapters/postgresql/unknown_srid.rb
66
62
  - lib/activerecord-spatial/active_record/models/geography_column.rb
@@ -69,14 +65,19 @@ files:
69
65
  - lib/activerecord-spatial/active_record/models/spatial_ref_sys.rb
70
66
  - lib/activerecord-spatial/associations.rb
71
67
  - lib/activerecord-spatial/associations/active_record.rb
72
- - lib/activerecord-spatial/associations/active_record_3.rb
73
68
  - lib/activerecord-spatial/associations/base.rb
69
+ - lib/activerecord-spatial/associations/preloader/spatial_association.rb
70
+ - lib/activerecord-spatial/associations/reflection/spatial_reflection.rb
74
71
  - lib/activerecord-spatial/spatial_columns.rb
75
72
  - lib/activerecord-spatial/spatial_function.rb
76
73
  - lib/activerecord-spatial/spatial_scope_constants.rb
74
+ - lib/activerecord-spatial/spatial_scope_constants/postgis_2_0.rb
75
+ - lib/activerecord-spatial/spatial_scope_constants/postgis_2_2.rb
76
+ - lib/activerecord-spatial/spatial_scope_constants/postgis_legacy.rb
77
77
  - lib/activerecord-spatial/spatial_scopes.rb
78
78
  - lib/activerecord-spatial/version.rb
79
79
  - lib/tasks/test.rake
80
+ - test/.rubocop.yml
80
81
  - test/accessors_geographies_tests.rb
81
82
  - test/accessors_geometries_tests.rb
82
83
  - test/adapter_tests.rb
@@ -120,11 +121,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
120
121
  version: '0'
121
122
  requirements: []
122
123
  rubyforge_project:
123
- rubygems_version: 2.5.1
124
+ rubygems_version: 2.6.11
124
125
  signing_key:
125
126
  specification_version: 4
126
127
  summary: ActiveRecord Spatial gives AR the ability to work with PostGIS columns.
127
128
  test_files:
129
+ - test/.rubocop.yml
128
130
  - test/accessors_geographies_tests.rb
129
131
  - test/accessors_geometries_tests.rb
130
132
  - test/adapter_tests.rb
@@ -1,123 +0,0 @@
1
-
2
- module ActiveRecord
3
- module Associations
4
- class Builder::Spatial < Builder::HasMany #:nodoc:
5
- self.macro = SPATIAL_MACRO
6
- self.valid_options += VALID_SPATIAL_OPTIONS
7
- self.valid_options -= INVALID_SPATIAL_OPTIONS
8
- end
9
-
10
- class Preloader #:nodoc:
11
- class SpatialAssociation < HasMany #:nodoc:
12
- def records_for(ids)
13
- table_name = reflection.quoted_table_name
14
- join_name = model.quoted_table_name
15
- column = %{#{SPATIAL_JOIN_QUOTED_NAME}.#{model.quoted_primary_key}}
16
- geom = {
17
- :class => model,
18
- :table_alias => SPATIAL_JOIN_NAME
19
- }
20
-
21
- if reflection.options[:geom].is_a?(Hash)
22
- geom.merge!(reflection.options[:geom])
23
- else
24
- geom[:column] = reflection.options[:geom]
25
- end
26
-
27
- scoped.
28
- select(%{array_to_string(array_agg(#{column}), ',') AS "#{SPATIAL_FIELD_ALIAS}"}).
29
- joins(
30
- "INNER JOIN #{join_name} AS #{SPATIAL_JOIN_QUOTED_NAME} ON (" <<
31
- klass.send("st_#{reflection.options[:relationship]}",
32
- geom,
33
- (reflection.options[:scope_options] || {}).merge(
34
- :column => reflection.options[:foreign_geom]
35
- )
36
- ).where_values.join(' AND ') <<
37
- ")"
38
- ).
39
- where(model.arel_table.alias(SPATIAL_JOIN_NAME)[model.primary_key].in(ids)).
40
- group(table[klass.primary_key])
41
- end
42
- end
43
- end
44
-
45
- class AssociationScope #:nodoc:
46
- def add_constraints_with_spatial(scope)
47
- return add_constraints_without_spatial(scope) if !self.association.is_a?(SpatialAssociation)
48
-
49
- tables = construct_tables
50
-
51
- chain.each_with_index do |reflection, i|
52
- table, foreign_table = tables.shift, tables.first
53
-
54
- conditions = self.conditions[i]
55
- geom_options = {
56
- :class => self.association.klass
57
- }
58
-
59
- if self.association.geom.is_a?(Hash)
60
- geom_options.merge!(
61
- :value => owner[self.association.geom[:name]]
62
- )
63
- geom_options.merge!(self.association.geom)
64
- else
65
- geom_options.merge!(
66
- :value => owner[self.association.geom],
67
- :name => self.association.geom
68
- )
69
- end
70
-
71
- if reflection == chain.last
72
- scope = scope.send("st_#{self.association.relationship}", geom_options, self.association.scope_options)
73
-
74
- if reflection.type
75
- scope = scope.where(table[reflection.type].eq(owner.class.base_class.name))
76
- end
77
-
78
- conditions.each do |condition|
79
- scope = scope.where(interpolate(condition))
80
- end
81
- else
82
- constraint = scope.where(
83
- scope.send(
84
- "st_#{self.association.relationship}",
85
- owner[self.association.foreign_geom],
86
- self.association.scope_options
87
- ).where_values
88
- ).join(' AND ')
89
-
90
- if reflection.type
91
- type = chain[i + 1].klass.base_class.name
92
- constraint = table[reflection.type].eq(type).and(constraint)
93
- end
94
-
95
- scope = scope.joins(join(foreign_table, constraint))
96
-
97
- unless conditions.empty?
98
- scope = scope.where(sanitize(conditions, table))
99
- end
100
- end
101
- end
102
-
103
- scope
104
- end
105
- alias_method_chain :add_constraints, :spatial
106
- end
107
- end
108
- end
109
-
110
- module ActiveRecordSpatial::Associations
111
- module ClassMethods #:nodoc:
112
- def has_many_spatially(name, options = {}, &extension)
113
- options = build_options(options)
114
-
115
- if !ActiveRecordSpatial::SpatialScopeConstants::RELATIONSHIPS.include?(options[:relationship].to_s)
116
- raise ArgumentError.new(%{Invalid spatial relationship "#{options[:relationship]}", expected one of #{ActiveRecordSpatial::SpatialScopeConstants::RELATIONSHIPS.inspect}})
117
- end
118
-
119
- ActiveRecord::Associations::Builder::Spatial.build(self, name, options, &extension)
120
- end
121
- end
122
- end
123
-