DEV Community

EvanRPavone
EvanRPavone

Posted on

Partials - Ruby on Rails

Partials make your forms and pages easier to manage in Ruby. They are also very easy to setup and customize. In the project I am working on now, I am using a partial that has an if statement saying if there are any Trips show the calendar and all the information, if there are no trips have the user put in a new trip. Like so:

<div class="container m-auto my-4">
 <% unless current_user.trips.any? %>
   <%= render "trips_cta" %>
 <% else %>
   <%= render "trips_landing", trips: @trips %>
 <% end %>
</div>
Enter fullscreen mode Exit fullscreen mode

_trips_cta.html.erb

<div class="max-w-md my-10 m-auto lg:p-16 bg-white rounded border border-gray-100 text-center shadow">
    <%= image_tag "schedule.svg", alt: "schedule", width: 300, class: "mb-4" %>
    <h1 class="text-indigo-700 text-2xl mb-6">It looks like you haven't registered a team yet.</h1>
    <%= link_to "Register a new team", new_trip_path, class: "btn btn-orange py-3 px-5" %>
</div>
Enter fullscreen mode Exit fullscreen mode

_trips_landing.html.erb

<nav class="bg-white mb-4 shadow rounded">
    <ul id="nav-tab" class="tabs list-reset flex">
        <li class="active" data-tab="calendar">
            <%= link_to "#calendar", class: "tab flex items-center" do %>
                <svg viewBox="0 0 20 20" width="16" height="16" class="fill-current text-grey-100 mr-2"><title>calendar</title><path d="M1 4c0-1.1.9-2 2-2h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V4zm2 2v12h14V6H3zm2-6h2v2H5V0zm8 0h2v2h-2V0zM5 9h2v2H5V9zm0 4h2v2H5v-2zm4-4h2v2H9V9zm0 4h2v2H9v-2zm4-4h2v2h-2V9zm0 4h2v2h-2v-2z"></path></svg>
                Calendar
            <% end %>
        </li>
        <li data-tab="all-trips">
            <%= link_to "#all-trips", class: "tab flex items-center" do %>
                <%= image_tag "plane.svg", alt: "plane", width: 16, height: 16, class: "fill-current text-grey-100 mr-2" %>
                All Trips
            <% end %>
        </li>
    </ul>
</nav>

<div class="bg-white pg-10 border rounded">
    <div id="all-trips" class="tab-panel p-5">
        <h1 class="text-xl"><strong>Trips</strong></h1>

        <% trips.each do |trip| %>
            <div class="flex flex-wrap items-center justify-start p-4 border-b-2 border-grey-100 mb-6">
                <div class="flex-1 flex justify-between">
                    <div>
                        <%= link_to trip.team_name, trip, class: "btn-link mr-4"%>
                    </div>
...
Enter fullscreen mode Exit fullscreen mode

If the user has no trips, render the call to action partial. If the user has trips, render the landing page.

Let’s say you want to render a form on a page that already has content on it. You don’t want the file to use up so many lines of code, so you separate them using a partials. I have the trip show page, under the trip info I want to have a comment form but I don’t want to put the form on the show view for trips. Instead I want to make two new files, the form (_form.html.erb) for the comments and where the comments will be rendered after submission (_comments.html.erb). The show page would be setup like this:

   <%= render 'comments/form' %>
   <div id="comments">
     <%= render @trip.comments %>
   </div>
Enter fullscreen mode Exit fullscreen mode

So the form will be rendered and when the user submits a comment it will be put in the comments div.

The form would be setup like you would with any other form (I am using action text so this may look different from yours):

<p class="text-sm text-grey-700 my-2">comment as <%= current_user.name %></p>

<%= form_for([@trip, @comment], remote: true) do |f| %>
   <div class="relative">
       <%= f.rich_text_area :reply, id: "comment_reply_trix", class: 'input h-32 border border-grey-200 p-4 resize-none', placeholder: "add any notes or replies here" %>

       <%= f.submit class: 'btn btn-sm btn-orange block w-full text-center mt-2 lg: mt-0 lg:text-left lg:absolute lg:pin-b lg:pin-r lg:mb-2 lg:mr-2 lg:w-auto lg:inline-flex' %>
   </div>
<% end %>
Enter fullscreen mode Exit fullscreen mode

The comments would be setup like so:

<div class="flex items-start p-4 mt-4 border rounded">
   <div class="flex-1 pl-4 flex items-start justify-between">
       <div class="leading-normal">
           <p class="text-grey-700 text-xs"><%= comment.user.name %> commented <%= time_ago_in_words(comment.created_at) %> ago</p>
           <div class="text-grey-800"><%= sanitize comment.reply.to_plain_text %></div>
       </div>

       <% if author_of(comment) %>
           <%= link_to "Delete", trip_comment_path(comment.trip, comment), method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-red" %>
       <% end %>
   </div>
</div>
Enter fullscreen mode Exit fullscreen mode

If you want more information regarding rendering , you can visit Ruby on Rails Guides. Partials are easy and once you figure it out, your ruby on rails life will hopefully be a lot better.

Top comments (0)