Shoulda-matchers: validate_absence_of fails on Postgres array columns

Created on 29 Aug 2019  ·  3Comments  ·  Source: thoughtbot/shoulda-matchers

It looks like validate_absence_of doesn't work with array columns. For example, given a Rails application (using Postgres) that has migration with this line:

t.string :widgets, array: true

and the following model validations:

validates :widgets, absence: true

and the following test:

it { should validate_absence_of(:widgets) }

the matcher fails and produces the error below:

Expected SomeModel to validate that :widgets is empty/falsy, but
this could not be proved.
  After setting :widgets to ‹"an arbitrary value"› -- which was
  read back as ‹[]› -- the matcher expected the SomeModel to be
  invalid, but it was valid instead.

  As indicated in the message above, :widgets seems to be
  changing certain values as they are set, and this could have something
  to do with why this test is failing. If you've overridden the writer
  method for this attribute, then you may need to change it to make this
  test pass, or do something else entirely.

I think this is happening because the value chosen to test for presence (here) is the string "an arbitrary value". Because it's setting an array column, the string is being converted to [], so the test fails.

Ideally it would know that it's an array column and use something like ['an arbitrary value'] instead. There is an array method it could use in the Column class: @subject.class.columns_hash[@attribute.to_s].array.

Bug PR Welcome

All 3 comments

I would like to pick this up. 🤚

I accidentally hit the "assign yourself" button! My bad! :sweat_smile:

I accidentally hit the "assign yourself" button! My bad! 😅

No worries! 😁

Was this page helpful?
0 / 5 - 0 ratings