diff --git a/app/jobs/overland/batch_creating_job.rb b/app/jobs/overland/batch_creating_job.rb index 6c6ca3ea..c8166708 100644 --- a/app/jobs/overland/batch_creating_job.rb +++ b/app/jobs/overland/batch_creating_job.rb @@ -6,21 +6,23 @@ class Overland::BatchCreatingJob < ApplicationJob def perform(params, user_id) data = Overland::Params.new(params).call - data.each do |location| - next if point_exists?(location, user_id) - - Point.create!(location.merge(user_id:)) + records = data.map do |location| + { + lonlat: location[:lonlat], + timestamp: location[:timestamp], + user_id: user_id, + created_at: Time.current, + updated_at: Time.current + } end - end - private - - def point_exists?(params, user_id) - Point.exists?( - latitude: params[:latitude], - longitude: params[:longitude], - timestamp: params[:timestamp], - user_id: + # rubocop:disable Rails/SkipsModelValidations + Point.upsert_all( + records, + unique_by: %i[lonlat timestamp user_id], + returning: false, + on_duplicate: :skip ) + # rubocop:enable Rails/SkipsModelValidations end end diff --git a/app/jobs/points/create_job.rb b/app/jobs/points/create_job.rb index 964c50f7..7dc3d261 100644 --- a/app/jobs/points/create_job.rb +++ b/app/jobs/points/create_job.rb @@ -9,7 +9,7 @@ class Points::CreateJob < ApplicationJob data.each_slice(1000) do |location_batch| Point.upsert_all( location_batch, - unique_by: %i[latitude longitude timestamp user_id], + unique_by: %i[lonlat timestamp user_id], returning: false ) end diff --git a/app/models/trip.rb b/app/models/trip.rb index c216105d..098feb82 100644 --- a/app/models/trip.rb +++ b/app/models/trip.rb @@ -46,7 +46,7 @@ class Trip < ApplicationRecord end def calculate_path - trip_path = Tracks::BuildPath.new(points.pluck(:latitude, :longitude)).call + trip_path = Tracks::BuildPath.new(points.pluck(:lonlat)).call self.path = trip_path end diff --git a/app/services/overland/params.rb b/app/services/overland/params.rb index b712ffce..40c33599 100644 --- a/app/services/overland/params.rb +++ b/app/services/overland/params.rb @@ -13,8 +13,7 @@ class Overland::Params next if point[:geometry].nil? || point.dig(:properties, :timestamp).nil? { - latitude: point[:geometry][:coordinates][1], - longitude: point[:geometry][:coordinates][0], + lonlat: "POINT(#{point[:geometry][:coordinates][0]} #{point[:geometry][:coordinates][1]})", battery_status: point[:properties][:battery_state], battery: battery_level(point[:properties][:battery_level]), timestamp: DateTime.parse(point[:properties][:timestamp]), diff --git a/app/services/tracks/build_path.rb b/app/services/tracks/build_path.rb index 4feaf49c..a3e14b9c 100644 --- a/app/services/tracks/build_path.rb +++ b/app/services/tracks/build_path.rb @@ -7,7 +7,7 @@ class Tracks::BuildPath def call factory.line_string( - coordinates.map { |point| factory.point(point[1].to_f.round(5), point[0].to_f.round(5)) } + coordinates.map { |point| factory.point(point.lon.to_f.round(5), point.lat.to_f.round(5)) } ) end diff --git a/spec/services/overland/params_spec.rb b/spec/services/overland/params_spec.rb index 8ba3fd86..78bc5bf8 100644 --- a/spec/services/overland/params_spec.rb +++ b/spec/services/overland/params_spec.rb @@ -11,8 +11,7 @@ RSpec.describe Overland::Params do let(:expected_json) do { - latitude: 37.3318, - longitude: -122.030581, + lonlat: 'POINT(-122.030581 37.3318)', battery_status: 'charging', battery: 89, altitude: 0, @@ -31,8 +30,6 @@ RSpec.describe Overland::Params do it 'returns a hash with the correct keys' do expect(params[0].keys).to match_array( %i[ - latitude - longitude battery_status battery altitude @@ -43,6 +40,7 @@ RSpec.describe Overland::Params do tracker_id timestamp raw_data + lonlat ] ) end diff --git a/spec/services/tracks/build_path_spec.rb b/spec/services/tracks/build_path_spec.rb index 1d2db10a..e42dbb83 100644 --- a/spec/services/tracks/build_path_spec.rb +++ b/spec/services/tracks/build_path_spec.rb @@ -6,9 +6,9 @@ RSpec.describe Tracks::BuildPath do describe '#call' do let(:coordinates) do [ - [45.123456, -122.654321], # [lat, lng] - [45.234567, -122.765432], - [45.345678, -122.876543] + RGeo::Geographic.spherical_factory.point(-122.654321, 45.123456), + RGeo::Geographic.spherical_factory.point(-122.765432, 45.234567), + RGeo::Geographic.spherical_factory.point(-122.876543, 45.345678) ] end @@ -26,9 +26,9 @@ RSpec.describe Tracks::BuildPath do it 'correctly converts coordinates to points with rounded values' do points = result.points - coordinates.each_with_index do |(lat, lng), index| - expect(points[index].x).to eq(lng.to_f.round(5)) - expect(points[index].y).to eq(lat.to_f.round(5)) + coordinates.each_with_index do |coordinate_pair, index| + expect(points[index].x).to eq(coordinate_pair.lon.to_f.round(5)) + expect(points[index].y).to eq(coordinate_pair.lat.to_f.round(5)) end end end