本記事の目的
- railsで投稿を1段3分割にするやり方の共有
→作成するにあたり、意外にやり方が見つからなかったため
記事の対象
やり方
each_slice
メソッドを使う。
each_sliceメソッドはブロックに渡す要素数を指定することができる。
例えば、、、
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
numbers.each_slice(2) do |number1, number2|
puts " #{number1} : #{number2}"
end
↓↓↓↓↓↓↓↓↓↓↓
% ruby sample.rb
1 : 2
3 : 4
5 : 6
7 : 8
9 : 10
もし、配列の要素数が割り切れないと、最後の段のみ要素数が減る
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
numbers.each_slice(3) do |number1, number2, number3|
puts " #{number1} : #{number2}: #{number3}"
end
↓↓↓↓↓↓↓↓↓↓↓
% ruby sample.rb
1 : 2: 3
4 : 5: 6
7 : 8: 9
10 : :
実践
上で示したeach_sliceメソッドの使い方でだいたい検討がつくと思うが、使い方は同じ。
コントローラーのアクション内データベースから全ての投稿情報を取得し、インスタンス変数に代入してから、そのインスタンス変数に対して、each_sliceメソッドを使う。
自分のアプリケーションでは、ユーザー詳細ページ内で、ログインしているユーザーが投稿した情報を全て表示している。
def show
@records = @user.records.order("date DESC")
# ログインしユーザーの投稿を、選択した日付の降順で並び替えて全て取得
end
# @userには現在ログインしているユーザーの情報が代入されている。
# userモデルとrecord(記録)モデルを扱っているが、一対多の関係になっている。
<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">最終更新日時:<%= record1.updated_at.to_s(:datetime_jp) %></div>
</div>
<div class="skip-time-space">
<label class="question-rabel">どのくらいサボった?</label>
<div class="skip-time">
<%= "#{record1.time}分" %>
</div>
</div>
<div class="text-space">
<label class="question-rabel">何してた?</label>
<div class="what-skip">
<%= record1.skip %>
</div>
<label class="question-rabel">何すべきだった?</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">最終更新日時:<%= record2.updated_at.to_s(:datetime_jp) %></div>
</div>
<div class="skip-time-space">
<label class="question-rabel">どのくらいサボった?</label>
<div class="skip-time">
<%= "#{record2.time}分" %>
</div>
</div>
<div class="text-space">
<label class="question-rabel">何してた?</label>
<div class="what-skip">
<%= record2.skip %>
</div>
<label class="question-rabel">何すべきだった?</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">最終更新日時:<%= record3.updated_at.to_s(:datetime_jp) %></div>
</div>
<div class="skip-time-space">
<label class="question-rabel">どのくらいサボった?</label>
<div class="skip-time">
<%= "#{record3.time}分" %>
</div>
</div>
<div class="text-space">
<label class="question-rabel">何してた?</label>
<div class="what-skip">
<%= record3.skip %>
</div>
<label class="question-rabel">何すべきだった?</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>
実際には部分テンプレートを用いているので、一部記述を変えてある。
ここでポイントになるのは、各投稿を表示するコードを、
<% if record1 != nil %>
<% end %>
<% if record2 != nil %>
<% end %>
<% if record3 != nil %>
<% end %>
この様に、分割したブロック変数がnilでなければ表示するという囲いを作ることである。
先ほどの、each_sliceメソッドの紹介の例では、要素数がeach_sliceメソッドで指定した値で割り切れない時は、最後の段のみ要素数が減ったが、Railsでは上記の様に囲いがないと、ビューファイルをレンダリングする時にエラーが発生する。
参考記事
-
Qiita(@ota-yukiさん)「each_sliceメソッドの使い方」
https://qiita.com/ota-yuki/items/ad91ffa8e95108ba3ef7
(2020年12月頭頃に閲覧) -
Rubyリファレンスマニュアル「instance method Enumerable#each_slice」
https://docs.ruby-lang.org/ja/latest/method/Enumerable/i/each_slice.html
(2021年1月15日閲覧)