You know the drill if you’ve validated the same rule on a few attributes. One presence validation is one matcher, and five of them turn into five nearly identical lines that don’t tell the next reader much:
it { is_expected.to validate_presence_of(:first_name) }
it { is_expected.to validate_presence_of(:last_name) }
it { is_expected.to validate_presence_of(:email) }
Shoulda Matchers 8.0 is out on RubyGems, and it gets rid of that repetition. It also moves the gem onto Ruby 4 and the latest Rails. Let’s dig in.
One matcher, many attributes
Validation matchers now can receive more than one attribute, so those three lines become one:
it { is_expected.to validate_presence_of(:first_name, :last_name, :email) }
Qualifiers apply to all of them, so a grouped expectation reads just as clearly as the one-at-a-time version:
it { is_expected.to validate_presence_of(:arms, :legs).allow_nil }
Grouping doesn’t cost you anything when a spec goes red. The failure message calls out each attribute that failed and why, so you still land right on the problem.
These eleven matchers currently support the multiple-attribute syntax:
validate_presence_ofvalidate_absence_ofvalidate_acceptance_ofvalidate_confirmation_ofvalidate_length_ofvalidate_numericality_ofvalidate_inclusion_ofvalidate_exclusion_ofvalidate_comparison_ofhave_readonly_attributehave_one_attached
Ready for Ruby 4
8.0 runs on Ruby 4. We also bumped the supported versions up to the latest stable Ruby and Rails, so the gem matches the stack your app is probably already on and you won’t have to hold your test suite back to upgrade.
Keeping up with Rails associations
Rails is shifting to a new deprecated associations API. 8.0 supports it, so your association matchers keep working as Rails changes. Nothing for you to do here.
Upgrading
The only breaking change in 8.0 is dropping support for end-of-life Ruby and Rails versions, specifically Rails 7.1 and Ruby 3.2. If you’re already on a current Ruby and Rails, the upgrade should be seamless. Bump the version, run your suite, and you’re done. The new multiple-attribute syntax is opt-in, so your existing matchers keep working exactly as before. If you’re still on Rails 7.1 or Ruby 3.2, stick with the 7.x line until you can move up.
Thank you
Thanks to everyone who helped make this release happen.
Bump your Gemfile to 8.0.1 and let us know what you’d like grouped next. The
full list of changes is in the CHANGELOG. Enjoy!