It's never a good idea for partials to reference a global variable, such variable would be current_user. DHH mentioned this 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:
<head> <meta name="current_user" content="<%= current_user.json_info %>"> </head> json_info would contain the information that you need:
# 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:
<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:
// 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:
[..] 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:
<%= 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, 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 Jill Heyer on Unsplash

Top comments (0)