Опубликован: 27.01.2016 | Уровень: для всех | Доступ: платный
Лекция 7:

Регистрация

Успешная регистрация

Получив обработку отправки невалидной формы, теперь пришло время для завершения регистрационной формы, на самом деле сохранив нового пользователя (если валидный) в базу данных. Во-первых, мы попробуем сохранить пользователя; если сохранение пройдет успешно, информация пользователя будет записана в базу данных автоматически, а затем мы перенаправим браузер на страницу профиля пользователя (с дружеским приветствием), как это показано на наброске рис. 7.19. Если это не удастся, мы просто отступим к сценарию, разработанному в Разделе 7.3.

Набросок успешной регистрации.

Рис. 7.19. Набросок успешной регистрации.

Завершенная форма регистрации

Для того чтобы закончить работу с формой регистрации, нам необходимо заполнить закомментированный раздел в Листинге 7.21 соответствующим поведением. Сейчас тесты для отправки валидной формы должны быть провальными:

$ bundle exec rspec spec/requests/user_pages_spec.rb \
> -e "signup with valid information"

Это происходит из-за того что дефолтным поведением для Rails-действий является рендеринг соответствующего представления, но здесь нет (и не должно быть) представления соответствующего действию create. Вместо этого мы должны перенаправить на другую страницу и будет вполне логично если этой страницей будет профиль вновь созданного пользователя. Тестирование того что рендерится правильная страница оставлено в качестве упражнения (Раздел 7.6); код представлен в Листинге 7.26.

class UsersController < ApplicationController
  .
  .
  .
  def create
    @user = User.new(user_params)
    if @user.save
      redirect_to @user
    else
      render 'new'
    end
  end

  private

    def user_params
      params.require(:user).permit(:name, :email, :password,
                                   :password_confirmation)
    end
end
Листинг 7.26. Действие user create с сохранением и переадресацией. app/controllers/users_controller.rb

Обратите внимание на то что мы можем опустить user_path в редиректе, написав просто redirect_to @user для перенаправления на страницу показывающую пользователя.

С кодом в Листинге 7.26 наша регистрационная форма отлично работает, что вы можете проверить запустив набор тестов:

$ bundle exec rspec spec/

Флэш

Перед отправкой валидной регистрации в браузер мы собираемся немного отполировать ее, в соответствии с общепринятой в веб приложениях идеей: добавив сообщение, которое временно появляется на следующей странице (в данном случае, приветствуя нашего нового пользователя), а затем исчезает либо при посещении следующей страницы либо при перезагрузке текущей. Rails-способ сделать это состоит в использовании специальной переменной 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.

Мы можем организовать отображение содержимого флэш повсеместно на сайте, включив его в шаблон нашего приложения, как это показно в Листинге 7.27. (Этот код представляет из себя особенно уродливую комбинацию HTML и ERb; упражнение в Разделе 7.6 показывает как сделать его более красивым.)

<!DOCTYPE html>
<html>
  .
  .
  .
  <body>
    <%= render 'layouts/header' %>
    <div class="container">
      <% flash.each do |key, value| %>
        <div class="alert alert-<%= key %>"><%= value %></div>
      <% end %>
      <%= yield %>
      <%= render 'layouts/footer' %>
      <%= debug(params) if Rails.env.development? %>
    </div>
    .
    .
    .
  </body>
</html>
Листинг 7.27. Добавление содержимого переменной flash в шаблон сайта. app/views/layouts/application.html.erb

Код в Листинге 7.27 организует вставку каждого флэш элемента в div тег, с CSS классом, указывающим на тип сообщения. Например, если flash[:success] = "Welcome to the Sample App!", то код

<% flash.each do |key, value| %>
  <div class="alert alert-<%= key %>"><%= value %></div>
<% end %>

произведет такой HTML:

<div class="alert alert-success">Welcome to the Sample App!</div>

(Обратите внимание: ключ :success является символом, но встроенный Ruby автоматически конвертирует его в строку "success" перед вставкой в шаблон.) Причина, по которой мы перебираем все возможные пары ключ/значение заключается в том, что благодаря этому мы сможем включать другие виды флэш сообщений. Например, в Разделе 8.1.5 мы увидим flash[:error] используемое для индикации неудачной попытки входа на сайт.10На самом деле мы будем использовать тесно связанный flash.now, но мы отложим эти тонкости до тех пор пока они нам не понадобятся.

Написание теста на правильное флэш сообщение оставлено в качестве упражнения (Раздел 7.6) и мы можем получить прохождение теста назначив flash[:success] приветственное сообщение в действии create как это показано в Листинге 7.28.

class UsersController < ApplicationController
  .
  .
  .
  def create
    @user = User.new(user_params)
    if @user.save
      flash[:success] = "Welcome to the Sample App!"
      redirect_to @user
    else
      render 'new'
    end
  end

  private

    def user_params
      params.require(:user).permit(:name, :email, :password,
                                   :password_confirmation)
    end
end
Листинг 7.28. Добавление флеш сообщения к успешной регистрации пользователя. app/controllers/users_controller.rb

Первая регистрация

Вы можете увидеть результат всей этой работы, зарегистрировав нашего первого пользователя под именем "Rails Tutorial" и с адресом электронной почты "example@railstutorial.org". Получившаяся в результате страница ( рис. 7.20) показывает дружеское сообщение после успешной регистрации, включая приятный зеленый стиль для класса success, который был добавлен CSS фреймворком Bootstrap из Раздела 5.1.2. (Если вместо этого вы получили сообщение об ошибке указывающее на то что адрес электронной почты уже занят, убедитесь что вы выполнили db:reset Rake-задачу как это предлагалось сделать в Разделе 7.2.) Затем, после перезагрузки страницы профиля пользователя, флэш сообщение исчезает, как и было обещано ( рис. 7.21).

Результирующая страница успешной регистрации с флэш сообщением.

Рис. 7.20. Результирующая страница успешной регистрации с флэш сообщением.
Профиль пользователя с исчезнувшим после перезагрузки страницы флэш сообщением.

Рис. 7.21. Профиль пользователя с исчезнувшим после перезагрузки страницы флэш сообщением.

Теперь мы можем проверить нашу базу данных просто для того чтобы еще раз убедиться что новый пользователь действительно создан:

$ rails console
>> User.find_by(email: "example@railstutorial.org")
=> #<User id: 1, name: "Rails Tutorial", email: "example@railstutorial.org",
created_at: "2013-03-12 05:51:34", updated_at: "2013-03-12 05:51:34",
password_digest: "$2a$10$A58/j7wwh3aAffGkMAO9Q.jjh3jshd.6akhDKtchAz/R...">

Развертывание приложения на сервере с SSL

Мы разработали модель User и функционал регистрации, пришло время развернуть пример приложения на сервере. (Если вы еще не выполнили шаги из введения к Главе 3, вам следует вернуться и сделать это сейчас.) В рамках развертывания мы добавим Secure Sockets Layer (SSL)11Технически, SSL это теперь TLS, от Transport Layer Security, но все кого я знаю по-прежнему говорят "SSL". к продакшен приложению, тем самым обезопасив регистрацию. Поскольку мы будем реализовывать SSL на стороне сервера, пример приложения будет также обезопасен для входа пользователя (Глава 8) и также будет устойчив к уязвимости перехвата сессии (Раздел 8.2.1).

В качестве подготовки к развертыванию, вам следует объединить ваши изменения с master веткой:

$ git add .
$ git commit -m "Finish user signup"
$ git checkout master
$ git merge sign-up

Для того чтобы задеплоить приложение, нам для начала нужно добавить строку инициирующую использование SSL в продакшен. Получившийся в результате конфигурационный файл продакшен окружения config/environments/production.rb представлен в Листинге 7.29.

SampleApp::Application.configure do
  .
  .
  .
  # Force all access to the app over SSL, use Strict-Transport-Security,
  # and use secure cookies.
  config.force_ssl = true
  .
  .
  .
end
Листинг 7.29. Конфигурирование приложения для использования SSL в продакшен. config/environments/production.rb

Для того чтобы получить рабочий продакшен сайт, мы должны закоммитить изменения в конфигурационном файле и отправить результат на Heroku:

$ git commit -a -m "Add SSL in production"
$ git push heroku

Затем нам нужно запустить миграцию на продакшен базе данных для того чтобы сообщить Heroku о модели данных User

$ heroku run rake db:migrate

(Вы можете увидеть deprecation предупреждения в этой точке; просто игнорируйте их.)

Наконец, нам необходимо установить SSL на удаленном сервере. Конфигурирование продакшен сайта для использования SSL это довольно неприятная процедура, кроме всего прочего подразумевающая покупку SSL сертификата для вашего домена. К счастью, для приложений запущенных на домене Heroku (таких как наш Пример Приложения), мы можем упасть на хвост SSL сертификату Heroku. Если вы хотите запустить SSL на собственном домене, таком как , вам ничего не остается кроме как немного помучиться, о том как это правильно делать вы можете прочитать на Heroku странице о SSL.

Результатом всей этой работы является рабочая форма регистрации на продакшен сервере ( рис. 7.22):

$ heroku open

Обратите внимание на https:// вместо обычного http:// ( рис. 7.22). Дополнительная ‘s’ это указание на то что SSL работает.

Теперь вы можете посетить страницу регистрации и создать нового пользователя. Если возникнут какие-то проблемы, попробуйте выполнить

$ heroku logs

для того чтобы отловить ошибку с помощью логов Heroku.

Рабочая страница регистрации в Web.

Рис. 7.22. Рабочая страница регистрации в Web.
Вадим Обозин
Вадим Обозин

Здравствуйте, записался на курс. При этом ставил галочку на "обучаться с тьютором". На email пришло письмо, о том, что записался на самостоятельное изучение курса. Как выбрать тьютора?

Акбар Ахвердов
Акбар Ахвердов
Россия, г. Москва
Артём Зайцев
Артём Зайцев
Украина, ДНР