---
title: Control and document the variables of Ruby on Rails partials
url: https://sxnlabs.com/en/ruby/2023/11/09/rails-partials-strict-locals/
lang: en
date: '2023-11-09T11:40:00+02:00'
tags:
- Ruby
- Ruby on Rails
---

# Control and document the variables of Ruby on Rails partials

The **partials in Ruby on Rails** can quickly become **a nightmare** to manage because the only way to have the list of variables (locals in Rails jargon) used by a partial is to directly read its source code, which often contains several hundred lines of HTML code...

Since the release of **Ruby on Rails 7.1**, it is possible to use _magic comments_ at the top of your partials to constrain and document the use of locals in that partial.

Let's see right away how this works. 👏

Let's start by defining the partial's variables as follows:

```erb
# app/views/users/_user_card.html.erb

<%# locals: (name:, email:) -%>

My name is <%%= name %>
Reach me at <%%= email %>
```

Then, we pass these variables from the template in the `locals` _hash_.

```erb
# app/views/users/show.html.erb

<%%= render partial: "user_card",
  locals: {
    name: @user.name.full,
    email: @user.email
  }
%>
```

As defined, the variables `name` and `email` are mandatory, and their absence will cause an error.

Let's remove the email variable to see what happens.

```erb
# app/views/users/show.html.erb

<%%= render partial: "user_card",
  locals: {
    name: @user.name.full
  }
%>
```

An error is immediately raised.

```
ActionView::Template::Error (missing local: :email):

app/views/users/show.html.erb:1
```

Now, let's try to pass an undefined variable.

```erb
# app/views/users/show.html.erb

<%%= render partial: "user_card",
  locals: {
    name: @user.name.full,
    email: @user.email,
    phones: @user.phones
  }
%>
```

A new error is raised, this time to tell us that this variable is not accepted because it was not declared in the partial.

```
ActionView::Template::Error (unknown local: :phones):

app/views/users/show.html.erb:1
```

Thanks to these two errors, we are now certain of the variables accepted by our partial and we have at the same time gained a bit of documentation! 🎉

**Default Values**

It is possible to give default values to variables, which will allow us not to have to pass them each time we render.

```erb
# app/views/users/_user_card.html.erb

<%# locals: (name:, email:, phones: []) -%>

My name is <%%= name %>
Reach me at <%%= email %>
You can also give me a call at <%%= phones.join(", ") %>
```

This way, it is possible not to provide the `phones` variable to the partial without the call to the `join` method failing, because it has been called on `nil`.

**Disabling Variables**

If you do not want any variables to be passed to your partial, this is also possible!

```erb
# app/views/users/_user_card.html.erb

<%# locals: () -%>

My name is John
Reach me at john@doe.com
You can also give me a call at 0123456789
```

If we attempt to pass variables during rendering, the error below will be raised.

```
ActionView::Template::Error (no locals accepted):

app/views/users/show.html.erb:1
```

That concludes our little tour of this new feature in Rails 7.1, allowing us to exercise better control over the variables passed to our partials while documenting them.
