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/Gemfile CHANGED
@@ -2,20 +2,19 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- if RUBY_PLATFORM == "java"
6
- gem "activerecord-jdbcpostgresql-adapter"
5
+ if RUBY_PLATFORM == 'java'
6
+ gem 'activerecord-jdbcpostgresql-adapter'
7
7
  else
8
- gem "pg"
8
+ gem 'pg'
9
9
  end
10
10
 
11
- gem "rdoc", "~> 3.12"
12
- gem "rake", "~> 10.0"
13
- gem "minitest"
14
- gem "minitest-reporters"
15
- gem "guard-minitest"
16
- gem "simplecov"
17
-
18
- if File.exists?('Gemfile.local')
19
- instance_eval File.read('Gemfile.local')
20
- end
11
+ gem 'activerecord-testcase'
12
+ gem 'guard'
13
+ gem 'guard-minitest'
14
+ gem 'minitest'
15
+ gem 'minitest-reporters'
16
+ gem 'rake'
17
+ gem 'rdoc'
18
+ gem 'simplecov'
21
19
 
20
+ instance_eval File.read('Gemfile.local') if File.exist?('Gemfile.local')
data/Guardfile CHANGED
@@ -1,17 +1,14 @@
1
1
 
2
- guard 'minitest', :test_folders => 'test', :test_file_patterns => '*_tests.rb' do
3
- watch(%r|^test/(.+)_tests\.rb|)
2
+ guard 'minitest', test_folders: 'test', test_file_patterns: '*_tests.rb' do
3
+ watch(%r{^test/(.+)_tests\.rb})
4
4
 
5
- watch(%r|^lib/(.*)([^/]+)\.rb|) do |m|
6
- "test/#{m[1]}#{m[2]}_tests.rb"
5
+ watch(%r{^lib/(.*/)?([^/]+)\.rb$}) do |m|
6
+ "test/#{m[2]}_tests.rb"
7
7
  end
8
8
 
9
- watch(%r|^test/test_helper\.rb|) do
10
- "test"
9
+ watch(%r{^test/test_helper\.rb}) do
10
+ 'test'
11
11
  end
12
12
  end
13
13
 
14
- if File.exists?('Guardfile.local')
15
- instance_eval File.read('Guardfile.local')
16
- end
17
-
14
+ instance_eval File.read('Guardfile.local') if File.exist?('Guardfile.local')
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2010-2016 J Smith <dark.panda@gmail.com>
1
+ Copyright (c) 2010-2017 J Smith <dark.panda@gmail.com>
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person
4
4
  obtaining a copy of this software and associated documentation
data/README.rdoc CHANGED
@@ -107,31 +107,21 @@ See the test/database.yml file for example settings.
107
107
 
108
108
  == ActiveRecord Versions Supported
109
109
 
110
- We're starting to standardize on Rails 3+ for our purposes, so future versions
111
- this gem function on versions of Rails 3 and above. To use spatial scopes on
110
+ We're starting to standardize on Rails 5 for our purposes, so future versions
111
+ this gem function on versions of Rails 5 and above. To use spatial scopes on
112
112
  previous versions of ActiveRecord, see our geos-extensions gem available at
113
113
  https://github.com/dark-panda/geos-extensions . We have pulled the ActiveRecord
114
114
  extensions out of that gem and are instead packaging them here, thus allowing
115
115
  you to use the actual Geos extensions in an unfettered way. If you wish to
116
- use the spatial extensions with versions of Rails prior to 3, see versions of
117
- the geos-extensions gem prior to version 0.3.0 where the split occured.
118
-
119
- === Note About ActiveRecord 4.0.0
120
-
121
- Rails 4.0.0 introducted a backwards incompatible change involving `order`
122
- scopes where `ORDER BY` would be added in the opposite order compared to
123
- previous versions of Rails. This change was reverted in Rails 4.0.1. Because
124
- the change only lasted for a single version, we have decided that we will
125
- not be supporting Rails 4.0.0 and will only support versions of Rails that
126
- feature `order` scopes that are consistent with the behaviour prior to Rails
127
- 4.0.0. This includes Rails 4.0.1 and above.
116
+ use the spatial extensions with versions of Rails prior to 5, see versions of
117
+ the ActiveRecordSpatial gem prior to version 1.0.0.
128
118
 
129
119
  == PostGIS and PostgreSQL Versions Supported
130
120
 
131
- As of this writing, things look good for PostgreSQL 9.1 and 9.2 for both
132
- PostGIS 1.5 and 2.0. Some features are only available in PostGIS 2.0, such
133
- as the +st_3dintersects+ scope and the like, as that spatial relationship
134
- function was added in PostGIS 2.0.
121
+ As of this writing, things we test on PostgreSQL 9.4 and PostGIS 2.1+.
122
+ Some features are only available in PostGIS 2.0, such as the +st_3dintersects+
123
+ scope and the like, as that spatial relationship function was added in PostGIS
124
+ 2.0.
135
125
 
136
126
  PostgreSQL 9.0 and below are currently not supported as some of the SQL we
137
127
  produce to create the spatial queries is not supported in older PostgreSQL
@@ -176,4 +166,3 @@ most projects.
176
166
 
177
167
  This gem is licensed under an MIT-style license. See the +MIT-LICENSE+ file for
178
168
  details.
179
-
data/Rakefile CHANGED
@@ -7,7 +7,7 @@ require 'rake/testtask'
7
7
  require 'rdoc/task'
8
8
  require 'bundler/gem_tasks'
9
9
 
10
- $:.push File.expand_path(File.dirname(__FILE__), 'lib')
10
+ $LOAD_PATH.push File.expand_path(File.dirname(__FILE__), 'lib')
11
11
 
12
12
  version = ActiveRecordSpatial::VERSION
13
13
 
@@ -26,3 +26,4 @@ Rake::RDocTask.new do |t|
26
26
  t.rdoc_files.include('README.rdoc', 'MIT-LICENSE', 'lib/**/*.rb')
27
27
  end
28
28
 
29
+ task default: :test
@@ -3,25 +3,24 @@
3
3
  require File.expand_path('../lib/activerecord-spatial/version', __FILE__)
4
4
 
5
5
  Gem::Specification.new do |s|
6
- s.name = "activerecord-spatial"
6
+ s.name = 'activerecord-spatial'
7
7
  s.version = ActiveRecordSpatial::VERSION
8
8
 
9
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
10
- s.authors = ["J Smith"]
11
- s.description = "ActiveRecord Spatial gives AR the ability to work with PostGIS columns."
9
+ s.required_rubygems_version = Gem::Requirement.new('>= 0') if s.respond_to? :required_rubygems_version=
10
+ s.authors = ['J Smith']
11
+ s.description = 'ActiveRecord Spatial gives AR the ability to work with PostGIS columns.'
12
12
  s.summary = s.description
13
- s.email = "dark.panda@gmail.com"
14
- s.license = "MIT"
13
+ s.email = 'dark.panda@gmail.com'
14
+ s.license = 'MIT'
15
15
  s.extra_rdoc_files = [
16
- "README.rdoc"
16
+ 'README.rdoc'
17
17
  ]
18
- s.files = `git ls-files`.split($\)
18
+ s.files = `git ls-files`.split($OUTPUT_RECORD_SEPARATOR)
19
19
  s.executables = s.files.grep(%r{^bin/}).map { |f| File.basename(f) }
20
20
  s.test_files = s.files.grep(%r{^(test|spec|features)/})
21
- s.homepage = "https://github.com/dark-panda/activerecord-spatial"
22
- s.require_paths = ["lib"]
21
+ s.homepage = 'https://github.com/dark-panda/activerecord-spatial'
22
+ s.require_paths = ['lib']
23
23
 
24
- s.add_dependency("rails", [">= 3.2", "!= 4.0.0"])
25
- s.add_dependency("geos-extensions", [">= 0.3.0.dev"])
24
+ s.add_dependency('rails', ['>= 5.0'])
25
+ s.add_dependency('geos-extensions', ['>= 0.5'])
26
26
  end
27
-
@@ -0,0 +1,46 @@
1
+
2
+ module ActiveRecord
3
+ module Type
4
+ class Geometry < Value
5
+ def type
6
+ :geometry
7
+ end
8
+ end
9
+
10
+ class Geography < Value
11
+ def type
12
+ :geography
13
+ end
14
+ end
15
+ end
16
+
17
+ module ConnectionAdapters
18
+ module PostgreSQL
19
+ module OID
20
+ class Geometry < Type::Geometry
21
+ end
22
+
23
+ class Geography < Type::Geography
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::NATIVE_DATABASE_TYPES[:geometry] = {
31
+ name: 'geometry'
32
+ }
33
+
34
+ ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::NATIVE_DATABASE_TYPES[:geometry] = {
35
+ name: 'geography'
36
+ }
37
+
38
+ ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.class_eval do
39
+ prepend(Module.new do
40
+ def initialize_type_map(type_map)
41
+ super
42
+ type_map.register_type 'geometry', ::ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Geometry.new
43
+ type_map.register_type 'geography', ::ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Geography.new
44
+ end
45
+ end)
46
+ end
@@ -1,26 +1,15 @@
1
1
 
2
2
  require 'active_record/connection_adapters/postgresql_adapter'
3
+ require 'activerecord-spatial/active_record/connection_adapters/postgresql/adapter_extensions/active_record'
4
+
5
+ module ActiveRecordSpatial
6
+ autoload :POSTGIS, 'activerecord-spatial/active_record/connection_adapters/postgresql/postgis'
7
+ autoload :UNKNOWN_SRID, 'activerecord-spatial/active_record/connection_adapters/postgresql/unknown_srid'
8
+ autoload :UNKNOWN_SRIDS, 'activerecord-spatial/active_record/connection_adapters/postgresql/unknown_srid'
9
+ end
3
10
 
4
11
  module ActiveRecord
5
12
  module ConnectionAdapters
6
- class PostgreSQLColumn
7
- def simplified_type_with_spatial_type(field_type)
8
- case field_type
9
- # This is a special internal type used by PostgreSQL. In this case,
10
- # it is being used by the `geography_columns` view in PostGIS.
11
- when 'name'
12
- :string
13
- when /^geometry(\(|$)/
14
- :geometry
15
- when /^geography(\(|$)/
16
- :geography
17
- else
18
- simplified_type_without_spatial_type(field_type)
19
- end
20
- end
21
- alias_method_chain :simplified_type, :spatial_type
22
- end
23
-
24
13
  class PostgreSQLAdapter
25
14
  def geometry_columns?
26
15
  true
@@ -29,26 +18,6 @@ module ActiveRecord
29
18
  def geography_columns?
30
19
  ActiveRecordSpatial::POSTGIS[:lib] >= '1.5'
31
20
  end
32
-
33
- if defined?(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::OID)
34
- module OID
35
- class Spatial < Type
36
- def type_cast(value)
37
- value
38
- end
39
- end
40
-
41
- register_type 'geometry', OID::Spatial.new
42
- register_type 'geography', OID::Spatial.new
43
- end
44
- end
45
21
  end
46
22
  end
47
23
  end
48
-
49
- module ActiveRecordSpatial
50
- autoload :POSTGIS, 'activerecord-spatial/active_record/connection_adapters/postgresql/postgis'
51
- autoload :UNKNOWN_SRID, 'activerecord-spatial/active_record/connection_adapters/postgresql/unknown_srid'
52
- autoload :UNKNOWN_SRIDS, 'activerecord-spatial/active_record/connection_adapters/postgresql/unknown_srid'
53
- end
54
-
@@ -1,16 +1,16 @@
1
1
 
2
2
  module ActiveRecordSpatial
3
3
  POSTGIS = begin
4
- if (version_string = ::ActiveRecord::Base.connection.select_rows("SELECT postgis_full_version()").flatten.first).present?
4
+ if (version_string = ::ActiveRecord::Base.connection.select_rows('SELECT postgis_full_version()').flatten.first).present?
5
5
  hash = {
6
- :use_stats => version_string =~ /USE_STATS/
6
+ use_stats: version_string =~ /USE_STATS/
7
7
  }
8
8
 
9
9
  {
10
- :lib => /POSTGIS="([^"]+)"/,
11
- :geos => /GEOS="([^"]+)"/,
12
- :proj => /PROJ="([^"]+)"/,
13
- :libxml => /LIBXML="([^"]+)"/
10
+ lib: /POSTGIS="([^"]+)"/,
11
+ geos: /GEOS="([^"]+)"/,
12
+ proj: /PROJ="([^"]+)"/,
13
+ libxml: /LIBXML="([^"]+)"/
14
14
  }.each do |k, v|
15
15
  hash[k] = version_string.scan(v).flatten.first
16
16
  end
@@ -21,4 +21,3 @@ module ActiveRecordSpatial
21
21
  end
22
22
  end
23
23
  end
24
-
@@ -3,13 +3,13 @@ module ActiveRecordSpatial
3
3
  UNKNOWN_SRIDS = begin
4
4
  if ActiveRecordSpatial::POSTGIS[:lib] >= '2.0'
5
5
  {
6
- :geography => 0,
7
- :geometry => 0
6
+ geography: 0,
7
+ geometry: 0
8
8
  }.freeze
9
9
  else
10
10
  {
11
- :geography => 0,
12
- :geometry => -1
11
+ geography: 0,
12
+ geometry: -1
13
13
  }.freeze
14
14
  end
15
15
  end
@@ -18,4 +18,3 @@ module ActiveRecordSpatial
18
18
  ActiveRecordSpatial::UNKNOWN_SRIDS[:geometry]
19
19
  end
20
20
  end
21
-
@@ -10,8 +10,7 @@ module ActiveRecordSpatial
10
10
  end
11
11
 
12
12
  def spatial_column
13
- self.f_geography_column
13
+ f_geography_column
14
14
  end
15
15
  end
16
16
  end
17
-
@@ -10,8 +10,7 @@ module ActiveRecordSpatial
10
10
  end
11
11
 
12
12
  def spatial_column
13
- self.f_geometry_column
13
+ f_geometry_column
14
14
  end
15
15
  end
16
16
  end
17
-
@@ -11,7 +11,7 @@ module ActiveRecordSpatial
11
11
  self.inheritance_column = 'nonexistent_column_name_type'
12
12
 
13
13
  belongs_to :spatial_ref_sys,
14
- :foreign_key => :srid
14
+ foreign_key: :srid
15
15
  end
16
16
 
17
17
  def readonly?
@@ -19,4 +19,3 @@ module ActiveRecordSpatial
19
19
  end
20
20
  end
21
21
  end
22
-
@@ -5,16 +5,15 @@ module ActiveRecordSpatial
5
5
  self.primary_key = 'srid'
6
6
 
7
7
  has_many :geometry_columns,
8
- :foreign_key => :srid,
9
- :inverse_of => :spatial_ref_sys
8
+ foreign_key: :srid,
9
+ inverse_of: :spatial_ref_sys
10
10
 
11
11
  has_many :geography_columns,
12
- :foreign_key => :srid,
13
- :inverse_of => :spatial_ref_sys
12
+ foreign_key: :srid,
13
+ inverse_of: :spatial_ref_sys
14
14
 
15
15
  def spatial_columns
16
- self.geometry_columns + self.geography_columns
16
+ geometry_columns + geography_columns
17
17
  end
18
18
  end
19
19
  end
20
-
@@ -11,4 +11,3 @@ module ActiveRecordSpatial
11
11
  end
12
12
 
13
13
  require 'activerecord-spatial/associations'
14
-
@@ -1,146 +1,88 @@
1
- # encoding: UTF-8
2
1
 
3
2
  module ActiveRecord
4
- module Associations
5
- class Builder::Spatial < Builder::HasMany #:nodoc:
6
- def macro
7
- SPATIAL_MACRO
8
- end
9
-
10
- def valid_options
11
- super + VALID_SPATIAL_OPTIONS - INVALID_SPATIAL_OPTIONS
12
- end
13
- end
14
-
3
+ module Associations #:nodoc:
15
4
  class Preloader #:nodoc:
16
5
  class SpatialAssociation < HasMany #:nodoc:
17
- def records_for(ids)
18
- table_name = reflection.quoted_table_name
19
- join_name = model.quoted_table_name
20
- column = %{#{SPATIAL_JOIN_QUOTED_NAME}.#{model.quoted_primary_key}}
21
- geom = {
22
- :class => model,
23
- :table_alias => SPATIAL_JOIN_NAME
24
- }
25
-
26
- if reflection.options[:geom].is_a?(Hash)
27
- geom.merge!(reflection.options[:geom])
28
- else
29
- geom[:column] = reflection.options[:geom]
30
- end
6
+ private
31
7
 
32
- scoped = scope.
33
- select(%{array_to_string(array_agg(#{column}), ',') AS "#{SPATIAL_FIELD_ALIAS}"}).
34
- joins(
35
- "INNER JOIN #{join_name} AS #{SPATIAL_JOIN_QUOTED_NAME} ON (" <<
36
- klass.send("st_#{reflection.options[:relationship]}",
37
- geom,
38
- (reflection.options[:scope_options] || {}).merge(
39
- :column => reflection.options[:foreign_geom]
40
- )
41
- ).where_values.join(' AND ') <<
42
- ")"
43
- ).
44
- where(model.arel_table.alias(SPATIAL_JOIN_NAME)[model.primary_key].in(ids)).
45
- group(table[klass.primary_key])
46
-
47
- if reflection.options[:conditions]
48
- scoped = scoped.where(reflection.options[:conditions])
49
- end
8
+ def load_records(&block)
9
+ return {} if owner_keys.empty?
50
10
 
51
- scoped
52
- end
53
- end
54
- end
11
+ slices = owner_keys.each_slice(klass.connection.in_clause_length || owner_keys.size)
12
+ @preloaded_records = slices.flat_map do |slice|
13
+ records_for(slice).load(&block)
14
+ end
55
15
 
56
- class AssociationScope #:nodoc:
57
- def add_constraints_with_spatial(scope)
58
- return add_constraints_without_spatial(scope) if !self.association.is_a?(SpatialAssociation)
59
-
60
- tables = construct_tables
61
-
62
- chain.each_with_index do |reflection, i|
63
- table, foreign_table = tables.shift, tables.first
64
-
65
- geom_options = {
66
- :class => self.association.klass
67
- }
68
-
69
- if self.association.geom.is_a?(Hash)
70
- geom_options.merge!(
71
- :value => owner[self.association.geom[:name]]
72
- )
73
- geom_options.merge!(self.association.geom)
74
- else
75
- geom_options.merge!(
76
- :value => owner[self.association.geom],
77
- :name => self.association.geom
78
- )
16
+ @preloaded_records.each_with_object({}) do |record, memo|
17
+ keys = record[association_key_name].split(',')
18
+ keys.each do |key|
19
+ memo[key] ||= []
20
+ memo[key] << record
21
+ end
22
+ end
79
23
  end
80
24
 
81
- if reflection == chain.last
82
- scope = scope.send("st_#{self.association.relationship}", geom_options, self.association.scope_options)
83
-
84
- if reflection.type
85
- scope = scope.where(table[reflection.type].eq(owner.class.base_class.name))
86
- end
87
- else
88
- constraint = scope.where(
89
- scope.send(
90
- "st_#{self.association.relationship}",
91
- owner[self.association.foreign_geom],
92
- self.association.scope_options
93
- ).where_values
94
- ).join(' AND ')
95
-
96
- if reflection.type
97
- type = chain[i + 1].klass.base_class.name
98
- constraint = table[reflection.type].eq(type).and(constraint)
25
+ def associated_records_by_owner(_preloader)
26
+ records = load_records do |record|
27
+ record[association_key_name].split(',').each do |key|
28
+ owner = owners_by_key[convert_key(key)]
29
+ association = owner.association(reflection.name)
30
+ association.set_inverse_instance(record)
31
+ end
99
32
  end
100
33
 
101
- scope = scope.joins(join(foreign_table, constraint))
34
+ owners.each_with_object({}) do |owner, result|
35
+ result[owner] = records[convert_key(owner[owner_key_name])] || []
36
+ end
102
37
  end
38
+ end
39
+ end
103
40
 
104
- if reflection.options[:conditions].present?
105
- scope = scope.where(reflection.options[:conditions])
106
- end
41
+ class SpatialAssociation < HasManyAssociation #:nodoc:
42
+ def association_scope
43
+ return unless klass
107
44
 
108
- # Exclude the scope of the association itself, because that
109
- # was already merged in the #scope method.
110
- scope_chain[i].each do |scope_chain_item|
111
- klass = i == 0 ? self.klass : reflection.klass
112
- item = eval_scope(klass, scope_chain_item)
45
+ @association_scope ||= SpatialAssociationScope.scope(self, klass.connection)
46
+ end
113
47
 
114
- if scope_chain_item == self.reflection.scope
115
- scope.merge! item.except(:where, :includes)
116
- end
48
+ private
117
49
 
118
- scope.includes! item.includes_values
119
- scope.where_values += item.where_values
120
- scope.order_values |= item.order_values
121
- end
50
+ def get_records
51
+ scope.to_a
122
52
  end
53
+ end
123
54
 
124
- scope
55
+ class SpatialAssociationScope < AssociationScope #:nodoc:
56
+ INSTANCE = create
57
+
58
+ class << self
59
+ def scope(association, connection)
60
+ INSTANCE.scope(association, connection)
61
+ end
125
62
  end
126
- alias_method_chain :add_constraints, :spatial
127
- end
128
- end
129
- end
130
63
 
64
+ def last_chain_scope(scope, table, reflection, owner, assoc_klass)
65
+ geom_options = {
66
+ class: assoc_klass
67
+ }
68
+
69
+ if reflection.geom.is_a?(Hash)
70
+ geom_options[:value] = owner[reflection.geom[:name]]
71
+ geom_options.merge!(reflection.geom)
72
+ else
73
+ geom_options[:value] = owner[reflection.geom]
74
+ geom_options[:name] = reflection.geom
75
+ end
131
76
 
132
- module ActiveRecordSpatial::Associations
133
- module ClassMethods #:nodoc:
134
- def has_many_spatially(name, *args, &extension)
135
- options = build_options(args.extract_options!)
136
- scope = args.first
77
+ scope = scope.send("st_#{reflection.relationship}", geom_options, reflection.scope_options)
137
78
 
138
- if !ActiveRecordSpatial::SpatialScopeConstants::RELATIONSHIPS.include?(options[:relationship].to_s)
139
- raise ArgumentError.new(%{Invalid spatial relationship "#{options[:relationship]}", expected one of #{ActiveRecordSpatial::SpatialScopeConstants::RELATIONSHIPS.inspect}})
140
- end
79
+ if reflection.type
80
+ polymorphic_type = transform_value(owner.class.base_class.name)
81
+ scope = scope.where(table.name => { reflection.type => polymorphic_type })
82
+ end
141
83
 
142
- ActiveRecord::Associations::Builder::Spatial.build(self, name, scope, options, &extension)
84
+ scope
85
+ end
143
86
  end
144
87
  end
145
88
  end
146
-