.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)) ...