[RUBY] Divide the post into 3 rows (each_slice method)

Purpose of this article

--Sharing how to divide posts into 1 step and 3 with rails
→ Because I couldn't find a way to create it

Article target

--For those who want to divide posts into 1 step and 3 parts as shown in the image below with rails eachslice.png

manner

Use the each_slice method.

Each_slice method can specify the number of elements to pass to the block.

For example ...

sample.rb


numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

numbers.each_slice(2) do |number1, number2|
  puts " #{number1} : #{number2}"
end

↓↓↓↓↓↓↓↓↓↓↓

terminal


% ruby sample.rb

 1 : 2
 3 : 4
 5 : 6
 7 : 8
 9 : 10

If the number of elements in the array is not divisible, the number of elements will decrease only in the last row.

sample.rb


numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

numbers.each_slice(3) do |number1, number2, number3|
  puts " #{number1} : #{number2}: #{number3}"
end

↓↓↓↓↓↓↓↓↓↓↓

terminal


% ruby sample.rb

 1 : 2: 3
 4 : 5: 6
 7 : 8: 9
 10 : : 

Practice

I think you can think about how to use the each_slice method shown above, but the usage is the same.

Get all post information from the in-action database of the controller, assign it to an instance variable, and then use the each_slice method for that instance variable.

In my application, I see all the information posted by the logged-in user in the user details page.

users_controller.rb


def show
    @records = @user.records.order("date DESC")
    #Log in and get all user posts sorted in descending order of the selected date
end

# @The information of the currently logged-in user is assigned to user.
#user model and record(Record)I am dealing with a model, but it has a one-to-many relationship.

ruby:show.html.erb


<div class="card-space">
  <% @records.each_slice(3) do |record1,record2,record3| %>
    <div class="array-space">

      <% if record1 != nil %>
        <div class="card">
          <div class="date-wrapper">
            <% time1 = record1.date %>
            <div class="selected-date"><%= record1.date.strftime("%Y/%m/%d(#{@wd[time1.wday]})") %></div>
            <div class="last-updated-date">Last Modified:<%= record1.updated_at.to_s(:datetime_jp) %></div>
          </div>
          <div class="skip-time-space">
            <label class="question-rabel">How long did you skip</label>
            <div class="skip-time">
              <%= "#{record1.time}Minutes" %>
            </div>
          </div>
          <div class="text-space">
            <label class="question-rabel">What were you doing?</label>
            <div class="what-skip">
              <%= record1.skip %>
            </div>
            <label class="question-rabel">What should i have done</label>
            <div class="to-do">
              <%= record1.to_do %>
            </div>
          </div>
          <div class="update-btns">
            <%= link_to edit_record_path(record1.id), method: :get, class:"edit-link" do %>
              <i class="far fa-edit fa-2x"></i>
            <% end %>
            <%= link_to record_path(record1.id), method: :delete, class:"delete-link" do %>
              <i class="far fa-trash-alt fa-2x"></i>
            <% end %>
          </div> 
        </div> 
      <% end %>

      <% if record2 != nil %> 
        <div class="card">
          <div class="date-wrapper">
            <% time2 = record2.date %>
            <div class="selected-date"><%= record2.date.strftime("%Y/%m/%d(#{@wd[time2.wday]})") %></div>
            <div class="last-updated-date">Last Modified:<%= record2.updated_at.to_s(:datetime_jp) %></div>
          </div>
          <div class="skip-time-space">
            <label class="question-rabel">How long did you skip</label>
            <div class="skip-time">
              <%= "#{record2.time}Minutes" %>
            </div>
          </div>
          <div class="text-space">
            <label class="question-rabel">What were you doing?</label>
            <div class="what-skip">
                <%= record2.skip %>
            </div> 
            <label class="question-rabel">What should i have done</label>
            <div class="to-do">
              <%= record2.to_do %>
            </div>
          </div>
          <div class="update-btns">
            <%= link_to edit_record_path(record2.id), method: :get, class:"edit-link" do %> 
              <i class="far fa-edit fa-2x"></i>
            <% end %> 
            <%= link_to record_path(record2.id), method: :delete, class:"delete-link" do %>
              <i class="far fa-trash-alt fa-2x"></i>
            <% end %> 
          </div>
        </div>
      <% end %>

      <% if record3 != nil %>
        <div class="card">
          <div class="date-wrapper">
            <% time3 = record3.date %>
            <div class="selected-date"><%= record3.date.strftime("%Y/%m/%d(#{@wd[time3.wday]})") %></div>
            <div class="last-updated-date">Last Modified:<%= record3.updated_at.to_s(:datetime_jp) %></div>
          </div>
          <div class="skip-time-space">
            <label class="question-rabel">How long did you skip</label>
            <div class="skip-time">
              <%= "#{record3.time}Minutes" %>
            </div>
          </div>
          <div class="text-space">
            <label class="question-rabel">What were you doing?</label>
            <div class="what-skip">
                <%= record3.skip %>
            </div>
            <label class="question-rabel">What should i have done</label>
            <div class="to-do">
              <%= record3.to_do %>
            </div>
          </div>
          <div class="update-btns">
            <%= link_to edit_record_path(record3.id), method: :get, class:"edit-link" do %>
              <i class="far fa-edit fa-2x"></i>
            <% end %>
            <%= link_to record_path(record3.id), method: :delete, class:"delete-link" do %>
              <i class="far fa-trash-alt fa-2x"></i> 
            <% end %> 
          </div>
        </div>
      <% end %> 

    </div>
  <% end %>
</div>

Since a partial template is actually used, some descriptions have been changed.

The point here is the code to display each post,

<% if record1 != nil %>
 
<% end %>


<% if record2 != nil %>
 
<% end %>


<% if record3 != nil %>
 
<% end %>

In this way, it is to create an enclosure that displays if the divided block variable is not nil.

In the example of introducing the each_slice method earlier, when the number of elements is not divisible by the value specified by the each_slice method, the number of elements is reduced only in the last row, but in Rails, if there is no enclosure as described above, the view file I get an error when rendering.

Reference article

--Qiita (@ ota-yuki) "How to use each_slice method" https://qiita.com/ota-yuki/items/ad91ffa8e95108ba3ef7 (Viewed around the beginning of December 2020)

--Ruby reference manual "instance method Enumerable # each_slice" https://docs.ruby-lang.org/ja/latest/method/Enumerable/i/each_slice.html (Viewed on January 15, 2021)

Recommended Posts

Divide the post into 3 rows (each_slice method)
Divide the List into arbitrary numbers
About the method
Output about the method # 2
About the authenticate method.
About the map method
About the ancestors method
About the to_s method.