We were debugging one issue in our application which was caching the scope we had in where clause for first_or_create in model callbacks - and found one interesting issue -
Theconditions in the where clause
were cached in after_create
callback if we use where().first_or_create
, please check example below -
Example:
Contact.where(first_name: 'Kiprosh').first_or_create
Contact Model:
after_create :sanitize
def sanitize
Contact.where(creator_id: 123).solr_index
end
This should fire Contact.where(creator_id: 123)
but
instead fires Contact.where(first_name: 'Kiprosh', creator_id: 123)
On further checking for this issue and reading blogs we found reason for the issue is its implementation, please check the code below for understanding the issue -
scope = @user.contacts.where(creator_id: @sub_user.id)
scope.first || scope.create or scope.first || scope.scoping { Contact.create }
References -
- first_or_create is applying erroneous scope to model callbacks
- first_or_create is applying scope to callbacks
WORKAROUND
Contact.where().first_or_initialize.save
orContact.where(params).first || Contact.create(params)