Partials used for turbo streaming must be free of global references.
Tags: ruby, rails, stimulus
Published: 2023-07-08 13:21:02

---
title: Partials used for turbo streaming must be free of global references.
published: true
description: Partials used for turbo streaming must be free of global references.
tags: ruby, rails, stimulusjs
# cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o1h1m3adr8rns16cj4pl.png
# Use a ratio of 100:42 for best results.
# published_at: 2023-07-08 10:31 +0000
---

![A flower in the sand](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o1h1m3adr8rns16cj4pl.png)

It's never a good idea for partials to reference a global variable, such variable would be `current_user`. [DHH mentioned this](https://discuss.hotwired.dev/t/authentication-and-devise-with-broadcasts/1752/4) already and I'll show you how to gain access to the current user's information. I do it by storing information of the `current_user` in a `meta`:

```erb

<head>
  <meta name="current_user" content="<%= current_user.json_info %>">
</head>

```

`json_info` would contain the information that you need:

```rb
# user.rb

[..]

def json_info
  {
    id: self.id, 
    name: <NAME>,
    # Maybe full url to their avatar?
    avatar_url: Rails.application.routes.url_helpers.rails_blob_path(self.avatar, only_path: true)
  }.to_json
end

```

Basic stuff. With that, our `current_user` object lives inside the `meta` of the document `head`.

This partial will be a Stimulus controller and our partial is called `_message.html.erb` that lives inside the `shared` folder:

```erb
<article 
  data-controller="message" 
  id="<%= dom_id(message) %>" 
  data-author-id="<%= message.user.id %>">
   <%= message.body %>
</article>

```

Notice I have here `data-author-id`, very important, and I've connected a Stimulus controller. Every time this partial get's rendered in the DOM, the `connect` function gets triggered:

```js
// message_controller.js

import { Controller } from '@hotwired/stimulus'

export default class extends Controller {

  connect() {
    const currentUserBlob = this._getMetaValue('current_user');
    const id = JSON.parse(currentUserBlob).id

    const authorId = this.element.getAttribute('data-author-id')

    // Do something when authorId matches/does not match id.
    // This could be hiding/removing an element or something else.
  }

  _getMetaValue = (name) => {
    const element = document.head.querySelector(`meta[name="${name}"]`)
    return element?.getAttribute("content")
  }

}

```

Our message model `message.rb` would look something like this:

```rb

[..]

belongs_to :user
belongs_to :message_thread
has_rich_text :body

after_create_commit do
  # We cannot pass current user
  broadcast_append_to(self.message_thread, target: self.message_thread, partial: "shared/message", locals: { message: self })
end

```

`message.rb` is just an high-level example showing only the message object that was passed in and nothing else. Depending on what you're doing with "current_user", you'd implement that logic in the Stimulus controller's connect function.

The entire page may look like this:

```erb

<%= turbo_stream_from @thread %>

<section id="<%= dom_id(@thread) %>">
  <% @messages.each do |message|
    <%= render "shared/message", message: message %>
  <% end %>
</section>

```

As a rule of thumb, partials should be free from global references/objects but where a partial is used with ApplicationRenderer, you must connect it with a Stimulus controller to gain access to the `current_user`.

### 🎉 Self-promotion 🎉

I'm building [Farm Swop](https://farmswop.com), a platform for farmers where farmers can connect with nearby farmers to share/exchange support, machinery etc. It's in active development. Feel free to join to see my progress while I BuildInPublic.

Photo by <a href="https://unsplash.com/@jillheyer?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Jill Heyer</a> on <a href="https://unsplash.com/photos/03ztkGdYWU8?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a>