Skip to content

Commit 264fa46

Browse files
authored
Merge pull request #50 from culturecode/rails-8-support
Support Rails 8
2 parents 40d8deb + 1b3d0c3 commit 264fa46

21 files changed

Lines changed: 83 additions & 82 deletions

.github/workflows/ci.yml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,13 @@ jobs:
1111
runs-on: ubuntu-latest
1212
strategy:
1313
matrix:
14-
ruby-version: ["3.2"]
15-
gemfile: ["rails_7_0"]
14+
ruby-version: ["3.2", "4.0"]
15+
gemfile: ["rails_7_0", "rails_8_0"]
16+
exclude:
17+
- ruby-version: "4.0"
18+
gemfile: "rails_7_0"
19+
- ruby-version: "3.2"
20+
gemfile: "rails_8_0"
1621
fail-fast: false
1722

1823
env:
@@ -38,7 +43,7 @@ jobs:
3843
--health-retries 5
3944
4045
steps:
41-
- uses: actions/checkout@v2
46+
- uses: actions/checkout@v5
4247

4348
# libgeos and gdal are required and must be installed before `bundle install`
4449
# NB: if you add libs here that are required for Gem native extensions be sure to clear the

app/models/abstract_feature.rb

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ class AbstractFeature < ActiveRecord::Base
77
class_attribute :lowres_simplification
88
self.lowres_simplification = 2 # Threshold in meters
99

10-
belongs_to :spatial_model, :polymorphic => :true, :autosave => false
10+
belongs_to :spatial_model, polymorphic: :true, autosave: false
1111

1212
attr_writer :make_valid
1313

@@ -16,7 +16,7 @@ class AbstractFeature < ActiveRecord::Base
1616
validates_presence_of :geog
1717
validate :validate_geometry, if: :will_save_change_to_geog?
1818
before_save :sanitize, if: :will_save_change_to_geog?
19-
after_save :cache_derivatives, :if => [:automatically_cache_derivatives?, :saved_change_to_geog?]
19+
after_save :cache_derivatives, if: [:automatically_cache_derivatives?, :saved_change_to_geog?]
2020

2121
def self.cache_key
2222
collection_cache_key
@@ -41,15 +41,15 @@ def self.metadata_keys
4141
end
4242

4343
def self.polygons
44-
where(:feature_type => 'polygon')
44+
where(feature_type: 'polygon')
4545
end
4646

4747
def self.lines
48-
where(:feature_type => 'line')
48+
where(feature_type: 'line')
4949
end
5050

5151
def self.points
52-
where(:feature_type => 'point')
52+
where(feature_type: 'point')
5353
end
5454

5555
def self.within_distance_of_point(lat, lng, distance_in_meters, geom = 'geom_lowres')
@@ -59,7 +59,7 @@ def self.within_distance_of_point(lat, lng, distance_in_meters, geom = 'geom_low
5959
else "ST_Transform(ST_SetSRID(ST_Point(:lng, :lat), 4326), #{detect_srid(geom)})"
6060
end
6161

62-
binds = { :lng => lng.to_d, :lat => lat.to_d }
62+
binds = { lng: lng.to_d, lat: lat.to_d }
6363

6464
within_distance_of_sql(point_sql, distance_in_meters, geom, **binds)
6565
end
@@ -71,7 +71,7 @@ def self.within_distance_of_line(points, distance_in_meters, geom = 'geom_lowres
7171
else "ST_Transform(ST_SetSRID(:points::geometry, 4326), #{detect_srid(geom)})"
7272
end
7373

74-
binds = { :points => "LINESTRING(#{points.map {|coords| coords.join(' ') }.join(', ')})" }
74+
binds = { points: "LINESTRING(#{points.map {|coords| coords.join(' ') }.join(', ')})" }
7575

7676
within_distance_of_sql(point_sql, distance_in_meters, geom, **binds)
7777
end
@@ -83,14 +83,14 @@ def self.within_distance_of_polygon(points, distance_in_meters, geom = 'geom_low
8383
else "ST_Transform(ST_Polygon(:points::geometry, 4326), #{detect_srid(geom)})"
8484
end
8585

86-
binds = { :points => "LINESTRING(#{points.map {|coords| coords.join(' ') }.join(', ')})" }
86+
binds = { points: "LINESTRING(#{points.map {|coords| coords.join(' ') }.join(', ')})" }
8787

8888
within_distance_of_sql(point_sql, distance_in_meters, geom, **binds)
8989
end
9090

9191
def self.within_distance_of_sql(geometry_sql, distance_in_meters, features_column = 'geom_lowres', **binds)
9292
if distance_in_meters.to_f > 0
93-
where("ST_DWithin(features.#{features_column}, #{geometry_sql}, :distance)", **binds, :distance => distance_in_meters)
93+
where("ST_DWithin(features.#{features_column}, #{geometry_sql}, :distance)", **binds, distance: distance_in_meters)
9494
else
9595
where("ST_Intersects(features.#{features_column}, #{geometry_sql})", **binds)
9696
end
@@ -128,7 +128,7 @@ def self.valid
128128
end
129129

130130
def envelope(buffer_in_meters = 0)
131-
envelope_json = JSON.parse(self.class.select("ST_AsGeoJSON(ST_Envelope(ST_Buffer(features.geog, #{buffer_in_meters})::geometry)) AS result").where(:id => id).first.result)
131+
envelope_json = JSON.parse(self.class.select("ST_AsGeoJSON(ST_Envelope(ST_Buffer(features.geog, #{buffer_in_meters})::geometry)) AS result").where(id: id).first.result)
132132
envelope_json = envelope_json["coordinates"].first
133133

134134
raise "Can't calculate envelope for Feature #{self.id}" if envelope_json.blank?
@@ -257,12 +257,12 @@ def bounds
257257
end
258258

259259
def cache_derivatives(*args)
260-
self.class.default_scoped.where(:id => self.id).cache_derivatives(*args)
260+
self.class.default_scoped.where(id: self.id).cache_derivatives(*args)
261261
end
262262

263263
def kml(options = {})
264264
column = options[:lowres] ? 'geom_lowres' : 'geog'
265-
return SpatialFeatures::Utils.select_db_value(self.class.where(:id => id).select("ST_AsKML(#{column}, 6)"))
265+
return SpatialFeatures::Utils.select_db_value(self.class.where(id: id).select("ST_AsKML(#{column}, 6)"))
266266
end
267267

268268
def geojson(*args)
@@ -290,7 +290,7 @@ def self.detect_srid(column_name)
290290
end
291291

292292
def self.join_other_features(other)
293-
joins('INNER JOIN features AS other_features ON true').where(:other_features => {:id => other})
293+
joins('INNER JOIN features AS other_features ON true').where(other_features: {id: other})
294294
end
295295

296296
def validate_geometry

app/models/aggregate_feature.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
require_dependency SpatialFeatures::Engine.root.join('app/models/abstract_feature')
22

33
class AggregateFeature < AbstractFeature
4-
has_many :features, lambda { |aggregate| where(:spatial_model_type => aggregate.spatial_model_type) }, :foreign_key => :spatial_model_id, :primary_key => :spatial_model_id
4+
has_many :features, lambda { |aggregate| where(spatial_model_type: aggregate.spatial_model_type) }, foreign_key: :spatial_model_id, primary_key: :spatial_model_id
55

66
# Aggregate the features for the spatial model into a single feature
7-
before_validation :set_geog, :on => :create, :unless => :geog?
7+
before_validation :set_geog, on: :create, unless: :geog?
88

99
private
1010

app/models/feature.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ class Feature < AbstractFeature
77
class_attribute :lowres_precision
88
self.lowres_precision = 5
99

10-
has_one :aggregate_feature, lambda { |feature| where(:spatial_model_type => feature.spatial_model_type) }, :foreign_key => :spatial_model_id, :primary_key => :spatial_model_id
10+
has_one :aggregate_feature, lambda { |feature| where(spatial_model_type: feature.spatial_model_type) }, foreign_key: :spatial_model_id, primary_key: :spatial_model_id
1111

12-
scope :source_identifier, lambda {|source_identifier| where(:source_identifier => source_identifier) if source_identifier.present? }
12+
scope :source_identifier, lambda {|source_identifier| where(source_identifier: source_identifier) if source_identifier.present? }
1313

1414
before_save :truncate_name
1515

@@ -21,7 +21,7 @@ def self.defer_aggregate_refresh(&block)
2121
start_at = Feature.maximum(:id).to_i + 1
2222
output = without_aggregate_refresh(&block)
2323

24-
where(:id => start_at..Float::INFINITY).refresh_aggregates
24+
where(id: start_at..Float::INFINITY).refresh_aggregates
2525

2626
return output
2727
end
@@ -36,13 +36,13 @@ def self.without_aggregate_refresh
3636

3737
def self.refresh_aggregates
3838
# Find one feature from each spatial model and trigger the aggregate feature refresh
39-
ids = where.not(:spatial_model_type => nil)
40-
.where.not(:spatial_model_id => nil)
39+
ids = where.not(spatial_model_type: nil)
40+
.where.not(spatial_model_id: nil)
4141
.group('spatial_model_type, spatial_model_id')
4242
.pluck('MAX(id)')
4343

4444
# Unscope so that newly built AggregateFeatures get their type column set correctly
45-
AbstractFeature.unscoped { where(:id => ids).find_each(&:refresh_aggregate) }
45+
AbstractFeature.unscoped { where(id: ids).find_each(&:refresh_aggregate) }
4646
end
4747

4848
def refresh_aggregate

app/models/spatial_cache.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
class SpatialCache < ActiveRecord::Base
2-
belongs_to :spatial_model, :polymorphic => true, :inverse_of => :spatial_caches
2+
belongs_to :spatial_model, polymorphic: true, inverse_of: :spatial_caches
33

44
def self.between(spatial_model, klass)
55
where(SpatialFeatures::Utils.polymorphic_condition(spatial_model, 'spatial_model'))
6-
.where(:intersection_model_type => SpatialFeatures::Utils.class_name_with_ancestors(klass))
6+
.where(intersection_model_type: SpatialFeatures::Utils.class_name_with_ancestors(klass))
77
end
88

99
def stale?

app/models/spatial_proximity.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
class SpatialProximity < ActiveRecord::Base
2-
belongs_to :model_a, :polymorphic => true
3-
belongs_to :model_b, :polymorphic => true
2+
belongs_to :model_a, polymorphic: true
3+
belongs_to :model_b, polymorphic: true
44

55
def self.between(scope1, scope2)
66
where condition_sql(scope1, scope2, <<~SQL.squish)

gemfiles/rails_6_1.gemfile

Lines changed: 0 additions & 5 deletions
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
source "https://rubygems.org"
22

3-
gem "activerecord", "~> 6.0", "< 6.1"
3+
gem "activerecord", "~> 8"
44

55
gemspec path: "../"

lib/spatial_features/caching.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,16 +69,16 @@ def self.clear_cache(klass = nil, clazz = nil)
6969
end
7070

7171
def self.clear_record_cache(record, klass)
72-
record.spatial_caches.where(:intersection_model_type => SpatialFeatures::Utils.class_name_with_ancestors(klass)).delete_all
72+
record.spatial_caches.where(intersection_model_type: SpatialFeatures::Utils.class_name_with_ancestors(klass)).delete_all
7373
SpatialProximity.between(record, klass).delete_all
7474
end
7575

7676
def self.create_spatial_proximities(record, klass)
7777
klass = klass.to_s.constantize
7878
klass_record = klass.new
7979

80-
scope = klass.within_buffer(record, default_cache_buffer_in_meters, :columns => :id, :intersection_area => true, :distance => true, :cache => false)
81-
scope = scope.where.not(:id => record.id) if klass.table_name == record.class.table_name # Don't calculate self proximity
80+
scope = klass.within_buffer(record, default_cache_buffer_in_meters, columns: :id, intersection_area: true, distance: true, cache: false)
81+
scope = scope.where.not(id: record.id) if klass.table_name == record.class.table_name # Don't calculate self proximity
8282
results = klass.connection.select_rows(scope.to_sql)
8383

8484
results.each do |id, distance, area|

lib/spatial_features/controller_helpers/spatial_extensions.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,29 +15,29 @@ def abstract_clear_feature_update_errors(models)
1515
end
1616

1717
def abstract_proximity_action(scope, target, distance, &block)
18-
@nearby_records = scope_for_search(scope).within_buffer(target, distance, :distance => true, :intersection_area => true).order('distance_in_meters ASC, intersection_area_in_square_meters DESC, id ASC')
18+
@nearby_records = scope_for_search(scope).within_buffer(target, distance, distance: true, intersection_area: true).order('distance_in_meters ASC, intersection_area_in_square_meters DESC, id ASC')
1919
@target = target
2020

2121
if block_given?
2222
block.call(@nearby_records)
2323
else
2424
respond_to do |format|
25-
format.html { render :template => 'shared/spatial/feature_proximity', :layout => false }
26-
format.kml { render :template => 'shared/spatial/feature_proximity' }
25+
format.html { render template: 'shared/spatial/feature_proximity', layout: false }
26+
format.kml { render template: 'shared/spatial/feature_proximity' }
2727
end
2828
end
2929
end
3030

3131
def abstract_venn_polygons_action(scope, target, &block)
32-
@venn_polygons = SpatialFeatures.venn_polygons(scope_for_search(scope).intersecting(target), target.class.where(:id => target), :target => target)
32+
@venn_polygons = SpatialFeatures.venn_polygons(scope_for_search(scope).intersecting(target), target.class.where(id: target), target: target)
3333
@klass = klass_for_search(scope)
3434
@target = target
3535

3636
if block_given?
3737
block.call(@venn_polygons)
3838
else
3939
respond_to do |format|
40-
format.kml { render :template => 'shared/spatial/feature_venn_polygons' }
40+
format.kml { render template: 'shared/spatial/feature_venn_polygons' }
4141
end
4242
end
4343
end
@@ -50,7 +50,7 @@ def scope_for_search(scope)
5050
if params.key?(:ids)
5151
ids = params[:ids]
5252
ids = ids.split(/\D/) if ids.is_a?(String)
53-
scope.where(:id => ids)
53+
scope.where(id: ids)
5454
else
5555
scope
5656
end

0 commit comments

Comments
 (0)