[RUBY] Some subtly different repetitive writing styles in Rails View

Overview

You'll see code like the one below. It's okay because there are 4 cases, but if there are 10 cases or if the nest is deep, it makes me sad. I want to write it easily and with few repetitions. I just try various things.

<ul>
  <li>
    <div>User name</div>
    <div><%= user.name %></div>
  </li>
  <li>
    <div>mail address</div>
    <div><%= user.email %></div>
  </li>
  <li>
    <div>sex</div>
    <div><%= user.sex == 1 ? 'male' : 'Female' %></div>
  </li>
  <li>
    <div>role</div>
    <div><%= user.role %></div>
  </li>
</ul>

1. For simple repetition

Draper and [Translate Active Record model](https://railsguides.jp/i18n.html#active-record%E3%83%A2%E3%83] % 87% E3% 83% AB% E3% 81% A7% E7% BF% BB% E8% A8% B3% E3% 82% 92% E8% A1% 8C% E3% 81% AA% E3% 81% 86 ) Is used to multiply as follows. If you can just repeat it, this is fine

<!-- sex_Add the text method to UserDecorator.-->
<ul>
  <% %i[name email sex_text role].each do |key| %>
    <li>
      <div><%= User.human_attribute_name(key) %></div>
      <div><%= user.send(key) %></div>
    </li>
  <% end %>
</ul>

2. For partial repetition

If something outside the model gets mixed in the middle, a simple loop won't work. The same description appears three or more times, but it can be reduced a little by doing the following

<ul>
  <% %i[name email].each do |key| %>
    <li>
      <div><%= User.human_attribute_name(key) %></div>
      <div><%= user.send(key) %></div>
    </li>
  <% end %>
  <!--I got an instruction to put in today's weather on the way-->
  <li>
    <div>today's weather</div>
    <div><%= Wheather.today %></div>
  </li>
  <% %i[sex_text role].each do |key| %>
    <li>
      <div><%= User.human_attribute_name(key) %></div>
      <div><%= user.send(key) %></div>
    </li>
  <% end %>
</ul>

3. Use Helper

I don't want to repeat the html description 3 times, so at least make it a method.

class UsersHelper
  def user_param_li(label, value)
    tag.li do
      tag.div(label) +
      tag.div(value)
    end
  end
end
<ul>
  <% %i[name email].each do |key| %>
    <%= user_param_li(User.human_attribute_name(key), user.send(key)) %>
  <% end %>
  <!--Put today's weather on the way-->
  <%= user_param_li('today's weather', Wheather.today) %>
  <% %i[sex_text role].each do |key| %>
    <%= user_param_li(User.human_attribute_name(key), user.send(key)) %>
  <% end %>
</ul>

4. Prepare a class

It's hard to read, and I'm sad because I can't see the structure repeatedly. Prepare the object.

#This object is "Service Object", "Presenter", "view"_It is called variously such as "object" and "PORO".
#For this role, I would call it Presenter.
class UserParamsPresenter
  attr_reader :user
  def initialize(user)
    @user = user
  end

  def params
    [
      user_param(:name),
      user_param(:email),
      wheather_param,
      user_param(:sex_text),
      user_param(:role),
    ]
  end

  private 

  def wheather_param
    ['today's weather', Wheather.today]
  end

  def user_param(key)
    [User.human_attribute_name(key), user.send(key)]
  end
end
<ul>
  <!--This Presenter can also be passed from the controller. I don't know which one is better-->
  <% UserParamsPresenter.new(user).params.each do |label, value| %>
    <%= user_param_li(label, value) %>
  <% end %>
</ul>

5. I overdo it, so I reflect on it and write it in an easy-to-understand manner even if I just look at View

In this case it might not have been so complicated. The designer is in trouble. Is it okay to write ruby code in erb for a moment? Presenter can be erased.

<%
  user_params = [
    [User.human_attribute_name(:name), user.name)],
    [User.human_attribute_name(:email), user.email)],
    ['today's weather', Wheather.today],
    [User.human_attribute_name(:sex_text), user.sex_text)],
    [User.human_attribute_name(:role), user.role)],
  ]
%>
<ul>
  <% user_params.each do |label, value| %>
    <%= user_param_li(label, value) %>
  <% end %>
</ul>

6. If it's only here, it seems easier to call in the first place

I've done something like Helper, Draper, and I18n, but can I write it pretty well without it? It's a hurry project.

<%
  user_params = [
    ['User name', user.name],
    ['mail address', user.email],
    ['today's weather', Wheather.today],
    ['sex', user.sex == 1 ? 'male' : 'Female'],
    ['role', user.role],
  ]
%>
<ul>
  <% user_params.each do |label, value| %>
    <li>
      <div><%= label %></div>
      <div><%= value %></div>
    </li>
  <% end %>
</ul>

Summary

With that feeling, many ways of writing come to my mind, and I have to go around. Of these, the only way to decide which one is better is to look at the market conditions. If there is a writing style that you haven't written much by yourself, please try to write it by moving your hand first. I will try to write it for the time being, and it will be tested whether the writing style was appropriate by changing the specifications after a few weeks and comments from colleagues.

Recommended Posts

Some subtly different repetitive writing styles in Rails View
View monthly calendar in Rails
Specify home view in rails app [root]
[Rails] Implementation of "notify notification in some way"
[Japanese localization] i18n rails Easy Japanese localization view display only
Implement iteration in View by rendering collection [Rails]