diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 8f6485095..ecc606549 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -354,7 +354,6 @@ Layout/MultilineMethodCallBraceLayout: Layout/MultilineMethodCallIndentation: Exclude: - 'app/api/v01/routes.rb' - - 'config/initializers/without_callback.rb' - 'test/api/v01/devices/fleet_reporting_test.rb' - 'test/api/v01/zonings_test.rb' - 'test/controllers/zonings_controller_test.rb' @@ -674,14 +673,6 @@ Lint/ParenthesesAsGroupedExpression: - 'app/views/stops/_show.json.jbuilder' - 'db/migrate/20160201165010_split_table_destination_to_visit.rb' -# Offense count: 1 -# This cop supports unsafe autocorrection (--autocorrect-all). -# Configuration parameters: AllowedImplicitNamespaces. -# AllowedImplicitNamespaces: Gem -Lint/RaiseException: - Exclude: - - 'config/initializers/without_callback.rb' - # Offense count: 1 # This cop supports unsafe autocorrection (--autocorrect-all). Lint/RedundantRequireStatement: @@ -1728,7 +1719,6 @@ Style/SoleNestedConditional: - 'app/models/vehicle.rb' - 'app/views/routes/_edit.json.jbuilder' - 'app/views/stops/_show.json.jbuilder' - - 'config/initializers/without_callback.rb' - 'lib/notifications.rb' # Offense count: 1 diff --git a/CHANGELOG.md b/CHANGELOG.md index b7f7166be..9117db9ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ - Increase zone border weight & Change edit marker style [#207](https://github.com/cartoway/planner-web/pull/207) ### Removed + - `skip_callback` was not thread safe [#214](https://github.com/cartoway/planner-web/pull/214) ### Fixed - Api-web: Remove blank header bar [#201](https://github.com/cartoway/planner-web/pull/201) diff --git a/app/jobs/importer_base.rb b/app/jobs/importer_base.rb index e300e4edc..434d665ce 100644 --- a/app/jobs/importer_base.rb +++ b/app/jobs/importer_base.rb @@ -43,55 +43,49 @@ def import(data, name, synchronous, options) @synchronous = synchronous dests = false refs = Hash.new - Destination.without_callback(:create, :before, :check_max_destination) do - Destination.without_callback(:validation, :before, :update_geocode) do - VehicleUsageSet.without_callback(:create, :before, :check_max_vehicle_usage_set) do - Customer.transaction do - before_import(name, data, options) - - dests = data.map.with_index{ |row, line| - # Switch from locale or custom to internal column name in case of csv - row = yield(row, line + 1 + (options[:line_shift] || 0)) - - next if row.empty? # Skip empty line - - begin - if (ref = uniq_ref(row)) - if refs.key?(ref) - raise ImportInvalidRef.new(I18n.t("destinations.import_file.#{ref.is_a?(Array) && ref[0].nil? ? 'refs_visit_duplicate' : 'refs_duplicate'}", refs: ref.is_a?(Array) ? ref.compact.join(' | ') : ref)) - elsif !options[:allow_duplicate] - refs[ref] = nil - end - end - - dest = import_row(name, row, line, options) - if dest.nil? - next - end - - if !@synchronous && Mapotempo::Application.config.delayed_job_use && dest.respond_to?(:delay_geocode) - dest.delay_geocode - end - dest - rescue ImportBaseError => e - if options[:ignore_errors] - @warnings << e unless @warnings.include?(e) - else - raise - end - end - } - raise ImportEmpty.new I18n.t('import.empty') if dests.all?(&:nil?) - yield(nil) - - options[:dests] = dests - - after_import(name, options) - - finalize_import(name, options) + Customer.transaction do + before_import(name, data, options) + + dests = data.map.with_index{ |row, line| + # Switch from locale or custom to internal column name in case of csv + row = yield(row, line + 1 + (options[:line_shift] || 0)) + + next if row.empty? # Skip empty line + + begin + if (ref = uniq_ref(row)) + if refs.key?(ref) + raise ImportInvalidRef.new(I18n.t("destinations.import_file.#{ref.is_a?(Array) && ref[0].nil? ? 'refs_visit_duplicate' : 'refs_duplicate'}", refs: ref.is_a?(Array) ? ref.compact.join(' | ') : ref)) + elsif !options[:allow_duplicate] + refs[ref] = nil + end + end + + dest = import_row(name, row, line, options) + if dest.nil? + next + end + + if !@synchronous && Mapotempo::Application.config.delayed_job_use && dest.respond_to?(:delay_geocode) + dest.delay_geocode + end + dest + rescue ImportBaseError => e + if options[:ignore_errors] + @warnings << e unless @warnings.include?(e) + else + raise end end - end + } + raise ImportEmpty.new I18n.t('import.empty') if dests.all?(&:nil?) + yield(nil) + + options[:dests] = dests + + after_import(name, options) + + finalize_import(name, options) end dests diff --git a/app/jobs/importer_destinations.rb b/app/jobs/importer_destinations.rb index 73e8bc23d..4ab6a5f4f 100644 --- a/app/jobs/importer_destinations.rb +++ b/app/jobs/importer_destinations.rb @@ -176,7 +176,7 @@ def before_import(_name, data, options) @existing_destinations_by_ref = {} @existing_visits_by_ref = {} @destinations_visits_attributes_by_ref = {} - @customer.destinations.where.not(ref: nil).find_each{ |destination| + @customer.destinations.includes_visits.where.not(ref: nil).find_each{ |destination| @existing_destinations_by_ref[destination.ref.to_sym] = destination @existing_visits_by_ref[destination.ref.to_sym] = Hash[destination.visits.map{ |visit| [visit.ref&.to_sym, visit]}] @destinations_visits_attributes_by_ref[destination.ref.to_sym] = Hash.new @@ -498,7 +498,8 @@ def bulk_import_destinations(destination_index_attributes_hash) import_result = Destination.import( destinations_attributes, on_duplicate_key_update: { conflict_target: [:id], columns: :all }, - validate: true, all_or_none: true, track_validation_failures: true + validate: true, all_or_none: true, track_validation_failures: true, + validate_with_context: :import ) raise ImportBulkError.new(import_errors_with_indices(slice_lines, slice_index, import_result.failed_instances)) if import_result.failed_instances.any? diff --git a/app/jobs/importer_vehicle_usage_sets.rb b/app/jobs/importer_vehicle_usage_sets.rb index 9fab1832b..d6911e201 100644 --- a/app/jobs/importer_vehicle_usage_sets.rb +++ b/app/jobs/importer_vehicle_usage_sets.rb @@ -243,6 +243,7 @@ def after_import(_name, _options) @vehicle_usage_set.vehicle_usages.each{ |vu| vu.assign_attributes Hash[@common_configuration.keys.select{ |k| excluded_keys.exclude? k }.map{ |k| [k, nil] }] } + @vehicle_usage_set.import_skip = true @vehicle_usage_set.save! end diff --git a/app/models/customer.rb b/app/models/customer.rb index 3312ee93d..69ce3290d 100644 --- a/app/models/customer.rb +++ b/app/models/customer.rb @@ -46,7 +46,7 @@ class Customer < ApplicationRecord has_many :stops_relations, inverse_of: :customer, autosave: true, dependent: :delete_all enum router_dimension: Router::DIMENSION - attr_accessor :deliverable_units_updated, :device, :exclude_users + attr_accessor :deliverable_units_updated, :device, :exclude_users, :migration_skip include HashBoolAttr store_accessor :router_options, :time, :distance, :avoid_zones, :isochrone, :isodistance, :traffic, :track, :motorway, :toll, :low_emission_zone, :trailers, :weight, :weight_per_axle, :height, :width, :length, :hazardous_goods, :max_walk_distance, :approach, :snap, :strict_restriction @@ -100,7 +100,8 @@ class Customer < ApplicationRecord before_save :devices_update_vehicles, prepend: true after_create :create_default_store, :create_default_vehicle_usage_set, :create_default_deliverable_unit - before_update :update_max_vehicles, :update_enable_multi_visits, :update_outdated + before_update :update_max_vehicles, :update_enable_multi_visits + before_update :update_outdated, unless: :migration_skip include RefSanitizer @@ -486,15 +487,13 @@ def update_enable_multi_visits destination.visits.each{ |visit| visit.ref ||= destination.ref visit.tags |= destination.tags + visit.internal_skip = true } destination.ref = nil destination.tag_ids = [] # Don't load all plans to update them... - Destination.without_callback(:save, :before, :update_tags) do - Visit.without_callback(:save, :before, :update_tags) do - destination.save! - end - end + destination.internal_skip = true + destination.save! } else self.destinations.each{ |destination| @@ -504,13 +503,11 @@ def update_enable_multi_visits destination.visits.each{ |visit| visit.ref = nil visit.tag_ids = [] + visit.internal_skip = true } # Don't load all plans to update them... - Destination.without_callback(:save, :before, :update_tags) do - Visit.without_callback(:save, :before, :update_tags) do - destination.save! - end - end + destination.internal_skip = true + destination.save! end } end diff --git a/app/models/destination.rb b/app/models/destination.rb index 35be55596..c48a63bdd 100644 --- a/app/models/destination.rb +++ b/app/models/destination.rb @@ -18,6 +18,9 @@ class Destination < Location default_scope { order(:id) } + attr_accessor :internal_skip + + belongs_to :customer has_many :visits, inverse_of: :destination, dependent: :delete_all accepts_nested_attributes_for :visits, allow_destroy: true has_many :tag_destinations @@ -29,7 +32,8 @@ class Destination < Location validate_consistency [:tags] before_create :check_max_destination - before_save :save_visits, :update_tags + before_save :save_visits + before_save :update_tags, unless: :internal_skip after_save -> { @tag_ids_changed = false } include RefSanitizer diff --git a/app/models/location.rb b/app/models/location.rb index 2f8327788..8e09f5eb5 100644 --- a/app/models/location.rb +++ b/app/models/location.rb @@ -44,7 +44,7 @@ class Location < ApplicationRecord validates_inclusion_of :geocoding_accuracy, in: 0..1, allow_nil: true, message: ->(*_) { I18n.t('activerecord.errors.models.location.geocoding_accuracy_outside_range') } validates_with LocalizationValidator, fields: [:street, :city, :lat, :lng] - before_validation :update_geocode + before_validation :update_geocode, unless: -> { validation_context == :import } before_update :update_outdated def position? diff --git a/app/models/planning.rb b/app/models/planning.rb index 9f250068a..02ac77358 100644 --- a/app/models/planning.rb +++ b/app/models/planning.rb @@ -638,10 +638,8 @@ def fetch_stops_status end end - Visit.without_callback(:update, :before, :update_outdated) do - # Do not flag route as outdated just for quantities change, route quantities are computed after loop - stops_map[s[:order_id]].visit.update(quantities: quantities) - end + # Do not flag route as outdated just for quantities change, route quantities are computed after loop + stops_map[s[:order_id]].visit.update(quantities: quantities, outdate_skip: true) routes_quantities_changed << stops_map[s[:order_id]].route end diff --git a/app/models/route.rb b/app/models/route.rb index 3195c6712..eee50842e 100644 --- a/app/models/route.rb +++ b/app/models/route.rb @@ -18,6 +18,8 @@ class Route < ApplicationRecord RELATION_ORDER_KEYS = %i[pickup_delivery order sequence] + attr_accessor :migration_skip + belongs_to :planning belongs_to :vehicle_usage, optional: true has_many :stops, inverse_of: :route, autosave: true, dependent: :delete_all, after_add: :update_stops_track, after_remove: :update_stops_track @@ -34,7 +36,7 @@ class Route < ApplicationRecord attribute :end, ScheduleType.new time_attr :start, :end - before_update :update_vehicle_usage, :update_geojson + before_update :update_vehicle_usage, :update_geojson, unless: :migration_skip after_initialize :assign_defaults, if: -> { new_record? } after_create :complete_geojson diff --git a/app/models/tag.rb b/app/models/tag.rb index 0f3f65027..fa89876e1 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -18,6 +18,8 @@ class Tag < ApplicationRecord ICON_SIZE = %w(small medium large).freeze + attr_accessor :migration_skip + default_scope { order(:label) } belongs_to :customer @@ -52,7 +54,7 @@ class Tag < ApplicationRecord include RefSanitizer - before_update :update_outdated + before_update :update_outdated, unless: :migration_skip before_destroy :set_routes after_destroy :reset_routes_geojson_point diff --git a/app/models/vehicle.rb b/app/models/vehicle.rb index 03ae53175..53275934e 100644 --- a/app/models/vehicle.rb +++ b/app/models/vehicle.rb @@ -24,6 +24,8 @@ class Vehicle < ApplicationRecord default_scope { order(:id) } + attr_accessor :migration_skip + belongs_to :customer belongs_to :router, optional: true has_many :vehicle_usages, inverse_of: :vehicle, dependent: :destroy, autosave: true @@ -61,7 +63,8 @@ class Vehicle < ApplicationRecord before_validation :check_router_options_format before_create :create_vehicle_usage before_save :nilify_router_options_blanks - before_update :update_outdated, :update_color + before_update :update_color + before_update :update_outdated, unless: :migration_skip include Consistency validate_consistency [:tags] diff --git a/app/models/vehicle_usage_set.rb b/app/models/vehicle_usage_set.rb index 040c92c7f..1842ec15d 100644 --- a/app/models/vehicle_usage_set.rb +++ b/app/models/vehicle_usage_set.rb @@ -18,6 +18,8 @@ class VehicleUsageSet < ApplicationRecord default_scope { order(:id) } + attr_accessor :import_skip + belongs_to :customer, inverse_of: :vehicle_usage_sets belongs_to :store_start, class_name: 'Store', inverse_of: :vehicle_usage_set_starts, optional: true belongs_to :store_stop, class_name: 'Store', inverse_of: :vehicle_usage_set_stops, optional: true @@ -57,7 +59,7 @@ class VehicleUsageSet < ApplicationRecord validates :max_ride_distance, numericality: true, allow_nil: true after_initialize :assign_defaults, if: :new_record? - before_create :check_max_vehicle_usage_set + before_create :check_max_vehicle_usage_set, unless: :import_skip before_update :update_outdated amoeba do diff --git a/app/models/visit.rb b/app/models/visit.rb index f48005d70..33c833431 100644 --- a/app/models/visit.rb +++ b/app/models/visit.rb @@ -44,6 +44,8 @@ class Visit < ApplicationRecord always_final: 3 } + attr_accessor :internal_skip, :outdate_skip + include TimeAttr attribute :time_window_start_1, ScheduleType.new attribute :time_window_end_1, ScheduleType.new @@ -65,8 +67,9 @@ class Visit < ApplicationRecord include Consistency validate_consistency([:tags]) { |visit| visit.destination.try :customer_id } - before_save :update_tags, :create_orders, :update_quantities - before_update :update_outdated + before_save :update_tags, unless: :internal_skip + before_save :create_orders, :update_quantities + before_update :update_outdated, unless: :outdate_skip after_save -> { @tag_ids_changed = false } include RefSanitizer diff --git a/config/initializers/without_callback.rb b/config/initializers/without_callback.rb deleted file mode 100644 index 8a432e527..000000000 --- a/config/initializers/without_callback.rb +++ /dev/null @@ -1,24 +0,0 @@ -require 'set' - -module ActiveSupport::Callbacks::ClassMethods - def without_callback(*args, &block) - # Get all Filters (meaning all callback names as symboles) - filters = get_callbacks(args.first) - .select { |c| c.kind == args.second } - .map(&:filter) - - unless filters.include?(args.last) - raise Exception.new("Attempt to suppress a non existing callback") if Rails.env.development? || Rails.env.test? - end - - mutex = Mutex.new - mutex.synchronize do - begin - skip_callback(*args) - yield - ensure - set_callback(*args) - end - end - end -end diff --git a/db/migrate/20170516093304_rename_icon_name_to_tags.rb b/db/migrate/20170516093304_rename_icon_name_to_tags.rb index 7e61d3d8a..37e2c169a 100644 --- a/db/migrate/20170516093304_rename_icon_name_to_tags.rb +++ b/db/migrate/20170516093304_rename_icon_name_to_tags.rb @@ -12,9 +12,8 @@ def up elsif tag.icon == 'user' tag.icon = 'fa-user' end - Tag.without_callback :update, :before, :update_outdated do - tag.save! validate: false - end + tag.migration_skip = true + tag.save!(validate: false) end end end @@ -35,9 +34,8 @@ def down else tag.icon = nil end - Tag.without_callback :update, :before, :update_outdated do - tag.save! validate: false - end + tag.migration_skip = true + tag.save!(validate: false) end end end diff --git a/db/migrate/20170516093305_move_trace_to_route.rb b/db/migrate/20170516093305_move_trace_to_route.rb index a4b0731ea..fcd9b377a 100644 --- a/db/migrate/20170516093305_move_trace_to_route.rb +++ b/db/migrate/20170516093305_move_trace_to_route.rb @@ -19,88 +19,85 @@ def icon_size stop_updated_at_copy = column_exists? :stops, :updated_at_copy new_routes = route_updated_at_copy ? "updated_at_copy IS NULL OR (updated_at - interval '10 seconds' > updated_at_copy)" : 'true' - Route.without_callback(:update, :before, :update_vehicle_usage) do - Route.without_callback(:update, :before, :update_geojson) do - Route.where(new_routes).includes({stops: {visit: [:tags, {destination: [:visits, :tags, :customer]}]}}).find_each{ |route| - previous_with_pos = route.vehicle_usage && route.vehicle_usage.default_store_start.try(&:position?) - - geojson_tracks = [] - route.stops.sort_by{ |s| s.route.vehicle_usage ? s.index : s.id }.each_with_index{ |stop, i| - if stop.position? && stop.active? - stop.no_path = route.vehicle_usage && !stop.trace && previous_with_pos - previous_with_pos = stop if stop.position? - - if stop.trace - geojson_tracks << { - type: 'Feature', - geometry: { - type: 'LineString', - polylines: stop.trace, - }, - properties: { - route_id: route.id, - color: stop.route.default_color, - drive_time: stop.drive_time, - distance: stop.distance - }.compact - }.to_json - end - end + Route.where(new_routes).includes({stops: {visit: [:tags, {destination: [:visits, :tags, :customer]}]}}).find_each{ |route| + previous_with_pos = route.vehicle_usage && route.vehicle_usage.default_store_start.try(&:position?) - stop.index = i + 1 unless stop.route.vehicle_usage - } + geojson_tracks = [] + route.stops.sort_by{ |s| s.route.vehicle_usage ? s.index : s.id }.each_with_index{ |stop, i| + if stop.position? && stop.active? + stop.no_path = route.vehicle_usage && !stop.trace && previous_with_pos + previous_with_pos = stop if stop.position? - if route.stop_trace + if stop.trace geojson_tracks << { type: 'Feature', geometry: { type: 'LineString', - polylines: route.stop_trace, + polylines: stop.trace, }, properties: { route_id: route.id, - color: route.default_color, - drive_time: route.stop_drive_time, - distance: route.stop_distance + color: stop.route.default_color, + drive_time: stop.drive_time, + distance: stop.distance }.compact }.to_json - elsif route.vehicle_usage && route.vehicle_usage.default_store_stop.try(&:position?) && route.stops.any?{ |s| s.active && s.position? } - route.stop_no_path = true end - - route.geojson_tracks = geojson_tracks unless geojson_tracks.empty? - - inactive_stops = 0 - geojson_points = route.stops.select(&:position?).map do |stop| - inactive_stops += 1 unless stop.active - if stop.position? - { - type: 'Feature', - geometry: { - type: 'Point', - coordinates: [stop.lng, stop.lat] - }, - properties: { - route_id: route.id, - index: stop.index, - active: stop.active, - number: stop.active && stop.route.vehicle_usage ? stop.index - inactive_stops : nil, - color: stop.is_a?(StopVisit) ? stop.default_color : nil, - icon: stop.icon, - icon_size: stop.icon_size - } - }.to_json - end - end.compact - - route.geojson_points = geojson_points unless geojson_points.empty? - - route.compute_quantities - - route.save!(validate: false) - } + end + + stop.index = i + 1 unless stop.route.vehicle_usage + } + + if route.stop_trace + geojson_tracks << { + type: 'Feature', + geometry: { + type: 'LineString', + polylines: route.stop_trace, + }, + properties: { + route_id: route.id, + color: route.default_color, + drive_time: route.stop_drive_time, + distance: route.stop_distance + }.compact + }.to_json + elsif route.vehicle_usage && route.vehicle_usage.default_store_stop.try(&:position?) && route.stops.any?{ |s| s.active && s.position? } + route.stop_no_path = true end - end + + route.geojson_tracks = geojson_tracks unless geojson_tracks.empty? + + inactive_stops = 0 + geojson_points = route.stops.select(&:position?).map do |stop| + inactive_stops += 1 unless stop.active + if stop.position? + { + type: 'Feature', + geometry: { + type: 'Point', + coordinates: [stop.lng, stop.lat] + }, + properties: { + route_id: route.id, + index: stop.index, + active: stop.active, + number: stop.active && stop.route.vehicle_usage ? stop.index - inactive_stops : nil, + color: stop.is_a?(StopVisit) ? stop.default_color : nil, + icon: stop.icon, + icon_size: stop.icon_size + } + }.to_json + end + end.compact + + route.geojson_points = geojson_points unless geojson_points.empty? + + route.compute_quantities + + route.migration_skip = true + route.save!(validate: false) + } remove_column :routes, :updated_at_copy if route_updated_at_copy remove_column :stops, :updated_at_copy if stop_updated_at_copy @@ -115,34 +112,30 @@ def down add_column :routes, :stop_trace, :text change_column :stops, :index, :integer, null: true - Route.without_callback(:update, :before, :update_vehicle_usage) do - Route.without_callback(:update, :before, :update_geojson) do - Route.includes({stops: {visit: [:tags, {destination: [:visits, :tags, :customer]}]}}).find_each{ |route| - next unless route.geojson_tracks - geojson_track_stop = nil - - if route.geojson_tracks - geojson_tracks = route.geojson_tracks.map{ |s| JSON.parse(s) } - if route.vehicle_usage && route.vehicle_usage.default_store_stop - geojson_track_stop = geojson_tracks[-1] - geojson_tracks = geojson_tracks[0..-2] - end - - if geojson_tracks - route.stops.select(&:position?).select(&:active).reject(&:no_path).zip(geojson_tracks).each{ |stop, coordinates| - if stop && coordinates - stop.trace = coordinates['geometry']['polylines'] - end - } + Route.includes({stops: {visit: [:tags, {destination: [:visits, :tags, :customer]}]}}).find_each{ |route| + next unless route.geojson_tracks + geojson_track_stop = nil + + if route.geojson_tracks + geojson_tracks = route.geojson_tracks.map{ |s| JSON.parse(s) } + if route.vehicle_usage && route.vehicle_usage.default_store_stop + geojson_track_stop = geojson_tracks[-1] + geojson_tracks = geojson_tracks[0..-2] + end + + if geojson_tracks + route.stops.select(&:position?).select(&:active).reject(&:no_path).zip(geojson_tracks).each{ |stop, coordinates| + if stop && coordinates + stop.trace = coordinates['geometry']['polylines'] end + } + end - route.stop_trace = geojson_track_stop['geometry']['polylines'] if geojson_track_stop - end - - route.save!(validate: false) - } + route.stop_trace = geojson_track_stop['geometry']['polylines'] if geojson_track_stop end - end + route.migration_skip = true + route.save!(validate: false) + } remove_column :routes, :geojson_tracks remove_column :routes, :geojson_points diff --git a/db/migrate/20180219090520_change_hstore_to_jsonb.rb b/db/migrate/20180219090520_change_hstore_to_jsonb.rb index 6921f0404..75fca0636 100644 --- a/db/migrate/20180219090520_change_hstore_to_jsonb.rb +++ b/db/migrate/20180219090520_change_hstore_to_jsonb.rb @@ -15,21 +15,19 @@ def up router.save!(validate: false) } - Customer.without_callback(:update, :before, :update_outdated) do - Customer.all.each { |customer| - next if customer.router_options.blank? || customer.router_options.empty? - customer = loop_and_assign_typed_values(customer) - customer.save!(validate: false) - } - end + Customer.all.each { |customer| + next if customer.router_options.blank? || customer.router_options.empty? + customer = loop_and_assign_typed_values(customer) + customer.migration_skip = true + customer.save!(validate: false) + } - Vehicle.without_callback(:update, :before, :update_outdated) do - Vehicle.all.each { |vehicle| - next if vehicle.router_options.blank? || vehicle.router_options.empty? - vehicle = loop_and_assign_typed_values(vehicle) - vehicle.save!(validate: false) - } - end + Vehicle.all.each { |vehicle| + next if vehicle.router_options.blank? || vehicle.router_options.empty? + vehicle = loop_and_assign_typed_values(vehicle) + vehicle.migration_skip = true + vehicle.save!(validate: false) + } end def down @@ -56,21 +54,19 @@ def down change_column_null :routers, :options, true change_column :routers, :options, "hstore USING jsonb_to_hstore(options)", default: {} - Customer.without_callback(:update, :before, :update_outdated) do - Customer.find_each { |customer| - next unless customer.router_options.nil? || customer.router_options.blank? || customer.router_options.empty? - customer.router_options = {} - customer.save!(validate: false) - } - end + Customer.find_each { |customer| + next unless customer.router_options.nil? || customer.router_options.blank? || customer.router_options.empty? + customer.router_options = {} + customer.migration_skip = true + customer.save!(validate: false) + } - Vehicle.without_callback(:update, :before, :update_outdated) do - Vehicle.find_each { |vehicle| - next unless vehicle.router_options.nil? || vehicle.router_options.blank? || vehicle.router_options.empty? - vehicle.router_options = {} - vehicle.save!(validate: false) - } - end + Vehicle.find_each { |vehicle| + next unless vehicle.router_options.nil? || vehicle.router_options.blank? || vehicle.router_options.empty? + vehicle.router_options = {} + vehicle.migration_skip = true + vehicle.save!(validate: false) + } Router.find_each { |router| next unless router.options.nil? || router.options.blank? || router.options.empty?