The bug fixing was very frustrating. Take a look at the following example:
class Model < ActiveRecord::Base
...
# Set a unique scoped number
validate do
errors.add(:scoped_unique, "is already taken") if parent_parent_model.parent_model.models(true).where(scoped_unique: scoped_unique).where.not(id: id).present?
end
before_validation on: :create do
self.scoped_unique = (parent_parent_model.parent_model.models(true).collect { | model | model.scoped_unique }.max.to_i || 0) + 1 if self.scoped_unique.nil?
end
...
end
This works just fine when you are creating a new model like this:
parent_model.models.create(...)
However using find_or_create_by it adds unexpectedly additional parameters to the scope the model itself with the parent_model (thus not restricting itself to parent_parent_model only)!
parent_model.models.create_with(...).find_or_create_by(...)
Turns out you have to unscope the whole query:
class Model < ActiveRecord::Base
...
# Set a unique scoped number
validate do
Model.unscoped do
errors.add(:scoped_unique, "is already taken") if parent_parent_model.parent_model.models(true).where(scoped_unique: scoped_unique).where.not(id: id).present?
end
end
before_validation on: :create do
Model.unscoped do
self.scoped_unique = (parent_parent_model.parent_model.models(true).collect { | model | model.scoped_unique }.max.to_i || 0) + 1 if self.scoped_unique.nil?
end
end
...
end