How do I render partial a block of code that has a JS function and a lot of references in body.html.erb?

Viewed 26

Hope I can phrase this question properly as I'm also getting a quite confused with partials. I have the following files:

./body.html.erb

./_sidebar.html.erb

Essentially, I'd like to paste all sidebar info into the body. It repeats itself quite a few times (in a few tabs) so I found a few resources saying that render partial is the correct way to re-call multiple blocks of code.

./body.html.erb looks like this: (essentially member_list returns data of users like username, image, etc as seen on the sidebar. It definitely has content in it and everything works when it is all within the body.html.erb file)

<div class="sidebar">
     <%= render partial: "sidebar", locals: { members: member_list } %>
</div>

./_sidebar.html.erb looks like this:


<div class="sidebar-content">
    <div class="sb-content-title">
            Members(<%= local_assigns[:members].count() %>)
    </div>
    <div class="member-list">
        <% local_assigns[:members].slice(0, 20).each do |user| %>
        <div class="member-img">
               <img width="46" height="46" src=<%= user.avatar_template.gsub('{size}', (46).to_s) %> class='avatar'>
        </div>
        <% end %>
    </div>
</div>

Here are my questions:

  1. What is causing my code not to work? Unfortunately I don't get any errors because of nginx (just the standard 500 error), but it works when I have the sidebar-content inside body.html.erb and replacing local_assigns[:members] to member_list.

  2. How do I declare multiple variables to pass on? Would it be like so:

<%= render partial: "sidebar", locals: { members: member_list , members_check: members_exist} %>
  1. How do I declare openTab in the locals of render partial if I adde the below code into the _sidebar.html.erb?
    <div class="see-members">
    <a onclick="openTab(event, 'Members')">see members <i class="fa-solid fa-arrow-right"></i> </a>
    </div>

TLDR

This works (body.html.erb):

<div class="sidebar">
    <div class="sidebar-content">
        <div class="sb-content-title">
                Members(<%= member_list.count() %>)
        </div>
        <div class="member-list">
            <% member_list.slice(0, 20).each do |user| %>
            <div class="member-img">
                   <img width="46" height="46" src=<%= user.avatar_template.gsub('{size}', (46).to_s) %> class='avatar'>
            </div>
            <% end %>
        </div>
    </div>

This doesn't (when separated into 2 files):

./body.html.erb

<div class="sidebar">
     <%= render partial: "sidebar", locals: { members: member_list } %>
</div>

./_sidebar.html.erb:


<div class="sidebar-content">
    <div class="sb-content-title">
            Members(<%= local_assigns[:members].count() %>)
    </div>
    <div class="member-list">
        <% local_assigns[:members].slice(0, 20).each do |user| %>
        <div class="member-img">
               <img width="46" height="46" src=<%= user.avatar_template.gsub('{size}', (46).to_s) %> class='avatar'>
        </div>
        <% end %>
    </div>
</div>
1 Answers

Ruby on Rails will always look in the current controller's view folder for a partial unless the partial name is prefixed with another folder name.

The official Rails Guides suggest placing shared partials in app/views/shared and then specifying that path when including the partial.

Place the partial at app/views/shared/_sidebar.html.erb and change the call in the body to this:

<div class="sidebar">
  <%= render partial: "shared/sidebar", locals: { members: member_list } %>
</div>
Related