DEV Community

Cover image for Comparing params.expect to params.require and params.fetch
Jess Alejo
Jess Alejo

Posted on • Edited on

Comparing params.expect to params.require and params.fetch

I recently started using params.expect in my new Rails 8 project. It looked cleaner and more convenient than the usual require(...).permit(...) approach I’d been using. While it worked well in my code, I wanted to take a step back and understand how it actually compares to the older methods like params.require and params.fetch.


params.require

params.require(:user).permit(:first_name, :last_name)
Enter fullscreen mode Exit fullscreen mode

This is the standard approach in Rails versions before 8. It explicitly requires that the :user key exists in the parameters. If it doesn't, Rails raises an ActionController::ParameterMissing error. After that, it permits only the specified attributes.

Pros:

  • Fails loudly if the expected key is missing.
  • Helps protect against mass-assignment vulnerabilities.
  • Well-documented and widely used in the Rails community.

Cons:

  • Slightly verbose, especially for nested structures.
  • Requires chaining requires and permit, which can feel repetitive.

params.fetch

params.fetch(:user, {}).permit(:first_name, :last_name)
Enter fullscreen mode Exit fullscreen mode

This approach attempts to fetch the :user key. If it's not found, it returns and empty hash instead of raising an error. It's more forgiving method, but it has trade-offs.

Pros:

  • Avoids exceptions when the key is missing.
  • Useful in cases where the key is optional.

Cons:

  • Silently fails back to an empty hash, which can hide bugs.
  • Not recommended when strict validation is needed.

params.expect (Rails 8+)

params.expect(user: [:first_name, :last_name])
Enter fullscreen mode Exit fullscreen mode

This method was introduced in Rails 8 as a more concise and strict way to handle parameters. It combines both the presence checking and attribute whitelisting in a single method call.

How it works:

  • Checks that :user exists in the parameters.
  • Ensures that only the listed attributes are allowed.
  • Raises an error if the structure does not match expectations.

Pros:

  • Cleaner syntax with less chaining.
  • Strict validation by default.
  • Easier to read, especially for nested or deeply structured parameters.

Cons:

  • Only available in Rails 8 and later.
  • May be unfamiliar to developers who haven't used the latest Rails versions.

Conclusion

If you are working on a Rails 8+ project, params.expect offers a more concise and expressive way to handle strong parameters. It replaces the need to separately call require and permit, while also enforcing strict structure validation.

For older version of Rails, or for developers who prefer explicit method chaining, params.require(...).permit(...) remains the reliable and well-understood approach.

Use params.fetch only when you have a clear reason to allow missing keys without raising an error; and be cautious about the risks it introduces.

This comparison helped me clarify when and why to use each method. I hope it helps others make more informed choices when writing controller logic in Rails.

Top comments (1)

Collapse
 
jamey_86 profile image
Jamey

Nice posting! Looking forward to collaborating with you