0

Rails devs! I got a "best practice" question here. So I'm dealing with something very simple but that it's enough for me to understand.

I got this header partial in my Rails views, and I'm using devise to authenticate users. I'm displaying in modals the login form and my register form, all good there. In my html.erb that would look like this:

<div class="modal fade" id="loginModal" tabindex="-1" role="dialog" aria-labelledby="loginModalTitle" aria-hidden="true">
    <div class="modal-dialog modal-dialog-centered modal-lg" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>
            
            <div class="modal-body">
                <%= render '/devise/sessions/new'%>
            </div>
        </div>
    </div>
</div>


<div class="modal fade" id="registerModal" tabindex="-1" role="dialog" aria-labelledby="registerModalTitle" aria-hidden="true">
    <div class="modal-dialog modal-dialog-centered modal-lg" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>
            
            <div class="modal-body">
                <%= render '/devise/registrations/new'%>
            </div>
        </div>
    </div>
</div>

Now, I don't know if I'm being picky here but, is there a way I can reduce both of these two partials in to one? Like for example:

<div class="modal fade" id="{dynamicId}" tabindex="-1" role="dialog" aria-labelledby="{dynamicModaltitle}" aria-hidden="true">
    <div class="modal-dialog modal-dialog-centered modal-lg" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>
            
            <div class="modal-body">
                <%= render '{dynamic partial view}'%>
            </div>
        </div>
    </div>
</div>

Probably that is not the correct syntax but I just want to make a point on what I want to achieve. I'm a very try believer of DRY code where I know there is a way to manage unrepeated code including in views itself. I will appreciate your help to achieve this.

theKid
  • 522
  • 6
  • 19

1 Answers1

2

You are on the right track: You can move the HTML part that is identical into a partial like this

# in app/views/shared/_modal.html.erb
<div class="modal fade" id="<%= name %>Modal" tabindex="-1" role="dialog" aria-labelledby="<%= name %>ModalTitle" aria-hidden="true">
    <div class="modal-dialog modal-dialog-centered modal-lg" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>
            
            <div class="modal-body">
                <%= yield %>
            </div>
        </div>
    </div>
</div>

and than render that model like this:

<%= render "shared/modal", name: 'login' do %>
  <%= render '/devise/sessions/new' %>
<% end %>

<%= render "shared/modal", name: 'register' do %>
  <%= render '/devise/registrations/new' %>
<% end %>

Note how the local variable name is used in the partial to generate the correct id and label. And how the yield in the partial will be replaced with the HTML provided in the block of the render call.

See Using Partials to Simplify Views from Layouts and Rendering in Rails from the Rails Guides.

spickermann
  • 100,941
  • 9
  • 101
  • 131
  • I would use `<%= tag.div id: "#{ name }Modal", ... do %>` instead of ERB interpolation in the middle of an attribute. – max Nov 21 '20 at 11:14