.strftime, или STR, формирующий формат TIME, является методом экземпляра Ruby из класса Time. Он позволяет форматировать объект Time в объект String, передавая директивы в качестве аргументов. Полный список опций см. в документации здесь.

Вот пример страницы index.html.erb, на которой указаны дата, заголовок, описание и стоимость расходов. .strftime используется для форматирования expense.created_at в удобочитаемую временную метку на нашей странице.

<h1>Expenses</h1>
<table>
  <thead>
    <tr>
      <th>Date</th>
      <th>Title</th>
      <th>Description</th>
      <th>Price</th>
    </tr>
  </thead>
  <% @expenses.each do |expense| %>
    <tbody>
      <tr>
        <td><%= expense.created_at.strftime('%B %d, %Y') %></td>
        <td><%= expense.title %></td>
        <td><%= expense.description %></td>        
        <td><%= number_to_currency(expense.amount) %><td>
      </tr>
    </tbody>
  <% end %>
</table>

Это все хорошо, и получается что-то вроде этого: October 17, 2017. Красивый!

Как извлечь .strftime во вспомогательный метод

К счастью, рельсы предполагают, что вам может понадобиться помощь в форматировании данных, возвращаемых вашими контроллерами; они точно названы, helpers. helpers, или вспомогательные методы, — это ruby-методы, которые можно вызывать из ваших шаблонов представлений и возвращать полезные и повторно используемые данные, обычно в форме String.

Вы, вероятно, уже знакомы с некоторыми из них; exepense_path, link_to и form_for — все это примеры методов, которые автоматически возвращают строки, чтобы помочь вашим представлениям оставаться динамичными и сухими. (В приведенном выше примере кода используется еще один, с которым вы, возможно, не знакомы: number_to_currency. Он включается с помощью модуля ActionView::Helpers::NumberHelper и используется для преобразования числа в строку валюты, см. документы.)

Чтобы создать собственный помощник, мы создадим и откроем файл expense_helper.rb, расположенный в каталоге app/helpers.

app
├── assets
├── channels
├── controllers
├── helpers
│   ├── application_helper.rb
│   └── expense_helper.rb                   <---------- There is is!

Затем мы определим наш метод внутри модуля anExpenseHelper.

module ExpenseHelper
  def full_date(datetime)
    datetime.strftime('%B %d, %Y')
  end
end

А затем замените наш вызов .strftime в нашем представлении вызовом нашего нового метода!

<td><%= full_date(expense.created_at) %></td>

Все вспомогательные модули автоматически включаются в наши представления, независимо от их пространства имен в каталоге /helpers.

Зачем беспокоиться?

D.R.Y. Мы все это знаем, и мы все любим это, иногда до такой степени, что жертвуем удобочитаемостью и выразительностью; нет недостатка в наградах за DRY умный код. В этом случае быть «СУХИМ» также значит быть выразительным! Вызов full_date и передача event.created_at гораздо более выразительны, чем .strftime(‘%B %d, %Y’). Директивы .strftime иногда в лучшем случае угадываются, но кто бы мог подумать, что передача '%B' дает вам полное название месяца??

Отвязка от тестов. Без нашего нового помощника наши тесты могли бы выглядеть примерно так

...
expect(page).to have_content(event.created_at.strftime('%B %d, %Y'))
...

Да, наши тесты зеленые, но что произойдет, если мы изменим представление и вместо этого получим что-то вроде Nov 17, 2017? Должны ли наши тесты начать терпеть неудачу? Я бы надеялся, что нет, но это то, чем мы закончим. Вместо этого мы можем использовать тот же вспомогательный метод, который мы использовали в нашем представлении в наших спецификациях, включив модуль, в котором мы его определили.

include ExpenseHelper
...
expect(page).to have_content(full_date(expense.created_at))
...