• Rails: How to fix issue with unique number under scope that doesn’t count correctly with find_or_create_by

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

The Author

Dan Schultzer is an active experienced entrepreneur, starting the Being Proactive groups, Dream Conception organization, among other things. You can find him at twitter

Like this post? More from Dan Schultzer

Comments? We would love to hear from you, write us at @dreamconception.