Skip to content

Commit

Permalink
Add docs for NonCaseSwappableValueError
Browse files Browse the repository at this point in the history
  • Loading branch information
mcmire committed Oct 9, 2015
1 parent e224e1d commit 80407e6
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 1 deletion.
4 changes: 3 additions & 1 deletion .yardopts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
--no-private
--protected
--readme README.md
--files NEWS.md
--markup markdown
--hide-tag return
--hide-tag param
-e ./doc_config/yard/setup.rb
-
NEWS.md
docs/**/*.md
111 changes: 111 additions & 0 deletions docs/errors/NonCaseSwappableValueError.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# @title NonCaseSwappableValueError

# NonCaseSwappableValueError

This error is raised when using `validate_uniqueness_of`. This matcher, of
course, tests that an attribute disallows a non-unique value -- and what
constitutes as "unique" depends on whether the case-sensitivity of that value
matters. If it does matter -- meaning that the uniqueness validation in your
model isn't using `case_sensitive: false` and you haven't qualified the matcher
with `case_insensitive` -- then the matcher will run the following test:

> Creating first a record with a value of "A":
>
> * A new record with a value of "A" should not be valid (failing the uniqueness
> validation)
> * A new record with a value of "a" should be valid
The test value we're using is in this case "A", and this is what the matcher
will use if an existing record is not already present in the database. But if
a record already exists, then the matcher will use it as comparison -- it will
read the attribute under test off of the record and use its value. So a better
example might be:

> Given an existing record with a value:
>
> * A new record with the same value should not be valid (failing the uniqueness
> validation)
> * A new record with the same value, but where the case is swapped (using
> String#swapcase), should be valid
Now, what happens if an existing record is there, but the value being used is
not one whose case can be swapped, such as `"123"` or `"{-#%}"`? Then the second
assertion cannot be made effectively.

So this is why you're getting this exception. What can you do about it? As the
error message explains, you have two options:

1. If you want the uniqueness validation in the model to operate
case-sensitively and you didn't mean to use a non-case-swappable value,
then you need to provide an existing record with a different value, one that
contains alpha characters. Here's an example:

# Model
class User < ActiveRecord::Base
validates_uniqueness_of :username
end

# RSpec
describe User do
context "validations" do
subject do
# Note that "123" == "123".swapcase. This is a problem!
User.new(username: "123")
end

it do
# So you can either override it like this, or just fix the subject.
user = User.create!(username: "john123")
expect(user).to validate_uniqueness_of(:username)
end
end
end

# Minitest (Shoulda)
class UserTest < ActiveSupport::TestCase
context "validations" do
subject do
# Note that "123" == "123".swapcase. This is a problem!
User.new(username: "123")
end

should "validate uniqueness of :username" do
# So you can either override it like this, or just fix the subject.
user = User.create!(username: "john123")
assert_accepts validate_uniqueness_of(:username), record
end
end
end

2. If you don't want the uniqueness validation to operate case-sensitively,
then you need to add `case_sensitive: false` to the validation and add
`case_insensitive` to the matcher:

# Model
class User < ActiveRecord::Base
validates_uniqueness_of :username, case_sensitive: false
end
# RSpec
describe User do
context "validations" do
subject do
# Note that "123" == "123".swapcase, but it's okay
User.new(username: "123")
end

it { should validate_uniqueness_of(:username).case_insensitive }
end
end
# Minitest (Shoulda)
class UserTest < ActiveSupport::TestCase
context "validations" do
subject do
# Note that "123" == "123".swapcase, but it's okay
User.new(username: "123")
end

should validate_uniqueness_of(:username).case_insensitive
end
end

0 comments on commit 80407e6

Please sign in to comment.