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'