---
title: 'Announcing Shoulda Matchers 8.0: validate multiple attributes in one line'
teaser: The latest Shoulda Matchers cuts repetitive validation specs down to a single
  line, runs on Ruby 4, and keeps up with the newest Rails.
tags: news,ruby,ruby on rails,testing,open source,shoulda
author: Matheus Sales
published_on: 2026-06-23
---

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:

```ruby
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][shoulda-matchers] 8.0 is out on [RubyGems][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:

```ruby
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:

```ruby
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_of`
* `validate_absence_of`
* `validate_acceptance_of`
* `validate_confirmation_of`
* `validate_length_of`
* `validate_numericality_of`
* `validate_inclusion_of`
* `validate_exclusion_of`
* `validate_comparison_of`
* `have_readonly_attribute`
* `have_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.

<aside class="info">
  <p>A heads up if you upgrade early: 8.0.0 shipped with a bug where <b>validate_uniqueness_of</b> raised an error when <code>config.enable_reloading</code> was false. That's fixed in 8.0.1, so go straight to 8.0.1.</p>
</aside>

## 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][changelog]. Enjoy!

[shoulda-matchers]: https://github.com/thoughtbot/shoulda-matchers
[rubygems]: https://rubygems.org/gems/shoulda-matchers
[changelog]: https://github.com/thoughtbot/shoulda-matchers/blob/main/CHANGELOG.md#800---2026-06-12
