user3574603
user3574603

Reputation: 3618

Rails 5: How do I test for uniquess at the database level when I also have validations on the model?

I have the following join table:

class ContactFormUsership < ApplicationRecord
  belongs_to :user
  belongs_to :contact_form

  validates :user_id, presence: true, uniqueness: { scope: :contact_form_id }
end

It ensures that there are no duplicate user/contact_form pairings when a row is created.

I also have indexes on that table to ensure the uniquess on the db level:

t.index ["user_id", "contact_form_id"], name: "index_contact_form_userships_on_user_id_and_contact_form_id", unique: true

I have a regression test that looks like this:

test 'An error is raised if a user is added to a form more than once' do
  contact_form = ContactForm.create
  user = users(:user_1)

  assert_raises(ActiveRecord::RecordInvalid) do
    2.times do
      contact_form.users << user
    end
  end
end

But this does not test that it is not possible to create duplicate rows at the db level. It only tests the validations.

How do I test uniqueness at a db level? Is there any way to << without validations?

Upvotes: 1

Views: 234

Answers (1)

Billy Kimble
Billy Kimble

Reputation: 820

Since you are trying to test the behavior of your ContactFormUsership table, you would do something like:

test 'An error is raised if a user is added to a form more than once' do
  contact_form = ContactForm.create
  user = users(:user_1)

  assert_raises(ActiveRecord::RecordInvalid) do
    c1 = ContactFormUsership.new(user: user, contact_form: contact_form)
    c1.save
    c2 = ContactFormUsership.new(user: user, contact_form: contact_form)
    c2.save(validate: false)
  end
end

You can find out more about validate: false at https://api.rubyonrails.org/classes/ActiveRecord/Validations.html

Upvotes: 3

Related Questions