Home > Enterprise >  Record being created multiple times in spite of validation (timing issue)
Record being created multiple times in spite of validation (timing issue)

Time:10-04

A webhook with lots of processing creates a record that has to go through this validation:

validates_uniqueness_of :pipedrive_deal_id, :allow_blank => true, scope: [:experience_id, :time], unless: -> { pipedrive_deal_id.zero? }

The processing of this webhook generates additional calls of the same webhook. This results in the same record being created 4 times, not respecting the validation shown above.

I "fixed" the issue by putting "sleep 5" on subsequent calls of the webhook, which apparently gives the initial process enough time to "close"? the validation and rejects any subsequent attempts to create it.

Is there a less hacky way to fix this issue?

Here's the code of the method (I have removed some things to make it clearer):

 def self.create_or_update_from_pipedrive(params, won_or_update,changed_values=nil)
    #this method calls the same webhook    
    hosting_link = PipedriveService.hosting_platform_setup(params[:id])
    if won_or_update == ('won')
        Payment.add_deal(params)
    else
    #this is the offending sleep 5
      sleep 5
    end
    #....internal processing
       if booking.update( booking_params)
      if booking.tour.present?
        if booking.tour.time != booking.time
          #this calls the webhook again
          booking.add_to_tour
        end
      end
    end
    if params[Rails.configuration.pipedrive_hash[:trip_details]].include? '40'
   
      if booking.update(booking_params)
        if booking.tour.present?
          if booking.tour.time != booking.time
    #this calls the webhook again
            booking.add_to_tour
          end
        end
      end
    #this calls the webhook again
         PipedriveService.set_post_session_activities(params, booking_time) if won_or_update == 'won'
  
  end

Thanks

CodePudding user response:

You need a unique index in the database. It is even mentioned in the official rails guides.

https://guides.rubyonrails.org/active_record_validations.html#uniqueness

This helper validates that the attribute's value is unique right before the object gets saved. It does not create a uniqueness constraint in the database, so it may happen that two different database connections create two records with the same value for a column that you intend to be unique. To avoid that, you must create a unique index on that column in your database.

CodePudding user response:

In case anyone stumbles upon my issue, the solution is (as suggested by the other answers) a unique index in the DB. As for the "unless attribute is zero" part, here is the whole migration command to add this as well:

add_index :bookings, [:pipedrive_deal_id, :time,:experience_id], unique: true, where: 'pipedrive_deal_id > 0'
  • Related