4

I'm having trouble with the following attributes within my class. I have a date attribute with presence true that is enforced at database level too:

validates :date, presence: true

In addition to that, I need to enforce combined uniqueness for the following two attributes

validates :name, uniqueness: { scope: :parent_id }

So far... everything is ok, but I want to have a spec testing the uniqueness

it { should validate_uniqueness_of(:name).scoped_to(:parent_id) }

But the problem with line above is that it will try to insert a record on db by just using a random name and parent_id values letting the date one to be nil. Thus, it fails on database.

I already tried doing subject { build(:my_model) } on the test, however the it line is still creating it's own one and not setting the date attribute.

How can I make shoulda to use the subject I created? I am missing something?

Pablo
  • 3,433
  • 7
  • 44
  • 62

1 Answers1

5

Shoulda matchers needs to create a separate record in the database to test the case where it is not unique. It skips rails validations to do this, but cannot skip your database validations. If you create one manually, it'll use that instead. Change your test to this:

subject { FactoryGirl.build(:my_model) }
it { should validate_uniqueness_of(:name).scoped_to(:parent_id) }

This is covered in more depth in the shoulda matchers documentation. http://www.rubydoc.info/github/thoughtbot/shoulda-matchers/Shoulda/Matchers/ActiveRecord#validate_uniqueness_of-instance_method

sgrif
  • 3,702
  • 24
  • 30
  • Thanks, it worked... although I still trying to figure out completely the explanation you gave. But thanks again – Pablo Jan 13 '14 at 02:11
  • Is there anything in particular I could clarify for you? (I'm a thoughtbot employee and work on shoulda-matchers so ask me anything) – sgrif Jan 14 '14 at 03:02
  • @sgrif, where does this 'create' method comes from? How this can be used with RSpec & FactoryGirl? I tried using FactoryGirl.create but shoulda still creates separate record. Thanks. – Alex Ponomarev Mar 30 '14 at 05:59
  • @sgrif An answer to Alex Ponomarev's comment would be very helpful. I have been trying to understand this for weeks. – Isaac Betesh Dec 29 '14 at 15:20
  • Yes, the `create` method comes from Factory girl. Looks like my answer was slightly wrong, I've updated with the correct code. I should point out that this exact question is answered thoroughly in the docs. http://www.rubydoc.info/github/thoughtbot/shoulda-matchers/Shoulda/Matchers/ActiveRecord#validate_uniqueness_of-instance_method – sgrif Dec 30 '14 at 18:16