mirror of
https://github.com/thoughtbot/shoulda-matchers.git
synced 2022-11-09 12:01:38 -05:00
Get validates_uniqueness_of to work better with NOT NULL
columns
Instead of having to persist the subject, like so: describe 'validations' do subject { build(:model) } it { validates_presence_of :required_attr } context "persisted" do # Needs to be persisted to prevent NOT NULL db error subject { create(:model) } it { validates_uniqueness_of :unique_attr } end end You can now just write: describe 'validations' do subject { build(:model) } it { validates_presence_of :required_attr } it { validates_uniqueness_of :unique_attr } end When required the matcher saves the record to the database.
This commit is contained in:
parent
dbf4900bf7
commit
6128af94fa
3 changed files with 36 additions and 5 deletions
6
NEWS.md
6
NEWS.md
|
@ -18,6 +18,12 @@
|
|||
* Fix `delegate_method` so that it can be required independent of Active
|
||||
Support.
|
||||
|
||||
* Fix `validate_uniqueness_of`. When used against an unpersisted record whose
|
||||
model contained a non-nullable column other than the one being validated, the
|
||||
matcher would break. Even if the test set that column to a value beforehand,
|
||||
the record had to be persisted in order for the matcher to work. Now this is
|
||||
no longer the case and the record can remain unpersisted.
|
||||
|
||||
### Improvements
|
||||
|
||||
* `have_and_belongs_to_many` now checks to make sure that the join table
|
||||
|
|
|
@ -209,6 +209,7 @@ module Shoulda
|
|||
end
|
||||
|
||||
def matches?(subject)
|
||||
@original_subject = subject
|
||||
@subject = subject.class.new
|
||||
@expected_message ||= :taken
|
||||
set_scoped_attributes &&
|
||||
|
@ -253,16 +254,20 @@ module Shoulda
|
|||
value = 'a'
|
||||
end
|
||||
|
||||
@subject.class.new.tap do |instance|
|
||||
@original_subject.tap do |instance|
|
||||
instance.__send__("#{@attribute}=", value)
|
||||
if has_secure_password?
|
||||
instance.password = 'password'
|
||||
instance.password_confirmation = 'password'
|
||||
end
|
||||
ensure_secure_password_set(instance)
|
||||
instance.save(validate: false)
|
||||
end
|
||||
end
|
||||
|
||||
def ensure_secure_password_set(instance)
|
||||
if has_secure_password?
|
||||
instance.password = "password"
|
||||
instance.password_confirmation = "password"
|
||||
end
|
||||
end
|
||||
|
||||
def has_secure_password?
|
||||
@subject.class.ancestors.map(&:to_s).include?('ActiveModel::SecurePassword::InstanceMethodsOnActivation')
|
||||
end
|
||||
|
|
|
@ -47,6 +47,26 @@ describe Shoulda::Matchers::ActiveModel::ValidateUniquenessOfMatcher do
|
|||
expect(Example.count).to eq 0
|
||||
expect(validating_uniqueness_with_other).to matcher
|
||||
end
|
||||
|
||||
context "and the table uses NOT NULL columns" do
|
||||
let(:model_class) do
|
||||
define_model(
|
||||
:example,
|
||||
attr: :string,
|
||||
required_attr: { type: :string, options: { null: false } }
|
||||
) do
|
||||
attr_accessible :attr, :required_attr
|
||||
validates_presence_of :required_attr
|
||||
validates_uniqueness_of :attr
|
||||
end
|
||||
end
|
||||
|
||||
it "works if the subject to sets the required attibutes" do
|
||||
model = model_class.new(required_attr: "foo")
|
||||
expect(Example.count).to eq 0
|
||||
expect(model).to matcher
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def define_model_with_other(options = {})
|
||||
|
|
Loading…
Reference in a new issue