8.3.3 Флэш
Перед отправкой валидной регистрации в браузер, мы собираемся немного отполировать ее, в соответствии с общепринятой в веб приложениях идеей: добавив сообщение, которое временно появляется, а затем исчезает при перезагрузке страницы. (Если сейчас что-то непонятно, будьте терпеливы; Конкретный пример появится в ближайшее время) Rails способ сделать это состоит в использовании специальной переменной flash, которая работает как флэш-память в том, что она хранит свои данные временно. Переменная flash
это на самом деле хэш; и вы можете даже вспомнить консольный например, в Разделе 4.3.3, где мы видели, как для перебора хэша использовался стратегически именованный хэш flash
. Чтобы вспомнить, попробуйте эту консольную сессию:
$ rails console
>> flash = { :success => "It worked!", :error => "It failed. :-(" }
=> {:success=>"It worked!", :error => "It failed. :-("}
>> flash.each do |key, value|
?> puts "#{key}"
?> puts "#{value}"
>> end
success
It worked!
error
It failed. :-(
Мы можем организовать отображение содержимого Флэш на веб-узле, включив его в макет нашего приложения, как в Листинге 8.16.
flash
переменной в макет сайта.app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
.
.
.
<%= render 'layouts/header' %>
<section class="round">
<% flash.each do |key, value| %>
<div class="flash <%= key %>"><%= value %></div>
<% end %>
<%= yield %>
</section>
.
.
.
</html>
Этот код организует вставку каждого флэш элемента в div
тег, с CSS классом, указывающим на тип сообщения. Например, если flash[:success] = "Welcome to the Sample App!"
, то код
<% flash.each do |key, value| %>
<div class="flash <%= key %>"><%= value %></div>
<% end %>
произведет такой HTML:6
<div class="flash success">Welcome to the Sample App!</div>
Причина, по которой мы перебираем все возможные пары ключ/значение заключается в том, что благодаря этому мы сможем включать другие виды флэш сообщений; например, в Листинге 9.8 мы увидим flash[:error]
используемое для индикации неудавшегося входа на сайт.7
Давайте протестируем флэш сообщение, чтобы убедиться в его правильности и в том, что оно появляется под ключом :success
(Листинг 8.17).
spec/controllers/users_controller_spec.rb
require 'spec_helper'
describe UsersController do
render_views
.
.
.
describe "POST 'create'" do
.
.
describe "success" do
.
.
.
it "should have a welcome message" do
post :create, :user => @attr
flash[:success].should =~ /welcome to the sample app/i
end
end
end
end
Это вводит “равно-тильда” =~ оператор для сравнения строк с регулярными выражениями. (Мы впервые увидели регулярные выражения в email_regex
Листинга 6.17). Вместо того, чтобы тестировать полное флэш сообщение, мы просто тестируем на существование “welcome to the sample app”. (Обратите внимание, что у нас еще нет теста для внешнего вида реального HTML флэш сообшений; мы исправим это тестированием фактического тега div
в Разделе 8.4.3.)
Если вы много программировали ранее, скорее всего, вы уже знакомы с регулярными выражениями, но вот быстрая console
сессия в случае если Вам необходимо введение:
>> "foo bar" =~ /Foo/ # Regex сравнение чувствительно к регистру по умолчанию.
=> nil
>> "foo bar" =~ /foo/
=> 0
Значения, возвращаемые здесь консолью, могут выглядеть странно: для несовпадения, regex сравнение возвращает nil
; для совпадения оно возвращает index (позицию, место) в строке где началось совпадение.8 Обычно точный индекс не имеет значения, так как сравнение, как правило, используется в булевом контексте: вспомните из Раздела 4.2.3 что nil
это false
в булевом контексте и что все остальное (даже 0
) является истиной. Таким образом, мы можем написать код, подобный этому:
>> success = "Welcome to the Sample App!"
=> "Welcome to the Sample App!"
>> "It's a match!" if success =~ /welcome to the sample app/
=> nil
Здесь нет совпадения, поскольку регулярные выражения чувствительны к регистру по умолчанию, но мы можем быть более снисходительными при сравнении, используя /.../i
чтобы добиться нечувствительного к регистру совпадения:
>> "It's a match!" if success =~ /welcome to the sample app/i
=> "It's a match!"
Теперь, когда мы понимаем, как работает сравнение регулярных выражений в тестах флэш, мы можем получить прохождение тестов, назначив flash[:success]
в действии create
как в Листинге 8.18. Сообщения используют различный регистр, но тесты пройдут в любом случае так как в конце регулярного выражения стоит i
. Таким образом, мы не испортим тест, если напишем, например, sample app
вместо Sample App
.
app/controllers/users_controller.rb
class UsersController < ApplicationController
.
.
.
def create
@user = User.new(params[:user])
if @user.save
flash[:success] = "Welcome to the Sample App!"
redirect_to @user
else
@title = "Sign up"
render 'new'
end
end
end