Опубликован: 27.01.2016 | Доступ: свободный | Студентов: 913 / 58 | Длительность: 23:07:00
Лекция 3:

В основном статические страницы

В этой главе мы начнем разработку примера приложения, которое будет служить нам образцом в остальной части этого учебника. Хотя в примере приложения, в конечном счете будут пользователи, сообщения и полная система входа и аутентификации, мы начнем с, казалось бы, ограниченной темы: с создания статических страниц. Несмотря на свою кажущуюся простоту, создание статических страниц весьма поучительное упражнение — идеальное начало для нашего зарождающегося приложения.

Хотя Rails предназначен для создания динамических веб сайтов, поддерживаемых базой данных, он также хорош при создании статических страниц, которые мы могли бы сделать на чистом HTML. В самом деле, использование Rails даже для статических страниц дает неоспоримое преимущество: мы можем легко добавлять лишь небольшое количество динамического содержания. В этой главе мы узнаем, как. По пути мы получим наш первый опыт автоматического тестирования, которое поможет нам быть более уверенными, в том, что наш код является правильным. Кроме того, хороший набор тестов позволит нам реорганизовывать (refactor) наш код с уверенностью, изменяя его форму, не меняя функций.

В этой главе довольно много кода, особенно в Разделе 3.2 и Разделе 3.3 и если вы новичок в Руби, вам не стоит беспокоиться о полном понимании происходящего. Как отмечалось в Разделе 1.1.1, один из возможных вариантов - копипастинг тестов и использование их для проверки кода приложения, не особо заботясь в этой точке о понимании того как они работают. К тому же, Глава 4 раскрывает тему Руби более полно, так что у этих идей будет масса возможностей осесть в вашей голове. Наконец, RSpec тесты будут часто повторяться на протяжении учебника, так что если вы застрянете, я рекомендую прорываться вперед; вы будете поражены тем, как, буквально через несколько глав, изначально непостижимый код совершенно внезапно окажется простым. (Вы также можете пройти RSpec курс в Code School, один из читателей сказал что он нашел в этом курсе ответы на бОльшую часть своих вопросов связанных с RSpec.)

Как и в Главе 2, перед началом работы нам необходимо создать новый Rails-проект, который мы в этот раз назовем sample_app:

$ cd ~/rails_projects
$ rails new sample_app --skip-test-unit
$ cd sample_app

Здесь --skip-test-unit опция команды rails говорит Rails не генерировать директорию test, связанную с дефолтным Test::Unit фреймворком. И это вовсе не потому что мы не хотим писать тесты; наоборот, начиная с Раздела 3.2 мы будем использовать альтернативный тестовый фреймворк RSpec для написания основательного набора тестов.

Как и в Разделе 2.1, нашим следующим шагом будет использование текстового редактора для добавления в Gemfile гемов, необходимых нашему приложению. Также, для примера приложения нам понадобятся два гема, в которых мы ранее не нуждались: гем для RSpec и гем для Rails-специфичной RSpec библиотеки. Код для их включения показан в Листинге 3.1. (Примечание: если вы хотите установить все гемы, необходимые для примера приложения, вам следует использовать код из Листинга 9.47 лекции 9.)

source 'https://rubygems.org'
ruby '2.0.0'
#ruby-gemset=railstutorial_rails_4_0

gem 'rails', '4.0.2'

group :development, :test do
  gem 'sqlite3', '1.3.8'
  gem 'rspec-rails', '2.13.1'
end

group :test do
  gem 'selenium-webdriver', '2.35.1'
  gem 'capybara', '2.1.0'
end

gem 'sass-rails', '4.0.1'
gem 'uglifier', '2.1.1'
gem 'coffee-rails', '4.0.1'
gem 'jquery-rails', '3.0.4'
gem 'turbolinks', '1.1.1'
gem 'jbuilder', '1.0.2'

group :doc do
  gem 'sdoc', '0.3.20', require: false
end

group :production do
  gem 'pg', '0.15.1'
  gem 'rails_12factor', '0.0.2'
end
Листинг 3.1. Gemfile для примера приложения.

Это включает rspec-rails в development mode , таким образом мы получаем доступ к RSpec-специфичным генераторам и это включает его в test mode где он нужен для запуска тестов. Нам нет надобности устанавливать сам RSpec, поскольку он является зависимостью гема rspec-rails и поэтому он будет установлен автоматически. Мы также включили гем Capybara, который позволит нам симулировать взаимодействие пользователя с нашим примером приложения используя понятный Англоподобный синтаксис, совместно с Selenium, одной из зависимостей Capybara’.1Преемник Webrat, Capybara назван в честь крупнейшего грызуна в мире. Как и в Главе 2, мы также должны включить pg и rails_12factor гемы в production для развертывания на Heroku:

group :production do
  gem 'pg', '0.15.1'
  gem 'rails_12factor', '0.0.2'
end

Heroku не рекомендует использовать разные базы данных для девелопмент и продакшн окружений; но для примера приложения это не будет иметь никакого значения, и SQLite намного проще чем PostgreSQL в установке и конфигурировании. Установку и конфигурирование PostgreSQL на вашей локальной машине остается в качестве амбициозного задания для авантюристов и мазохистов (Раздел 3.5).

Для установки и подключения новых гемов мы запускаем bundle update и bundle install:

$ bundle install --without production
$ bundle update
$ bundle install

Аналогично Разделу 1.4.1 и Главе 2, мы предотвратили установку продакшн гемов используя опцию --without production. Это "запоминаемая опция" и это означает что нам не придется добавлять ее каждый раз при вызове Bundler. Вместо этого мы можем просто писать bundle install и production гемы будут игнорированы автоматически.2Фактически, вы можете даже опустить install — bundle сам является алиасом для bundle install.

Поскольку наш пример приложения будет храниться в публичном репозитории, важно обновить так называемый secret token используемый в Rails для шифрования переменных связанных с сессией таким образом чтобы он генерировался динамически, а не был жестко прописан в коде (Листинг 3.2). (Код в Листинге 3.2 является довольно сложным для самого начала учебника, но, так как это может оказаться серьезной дырой в безопасности, я чувствую что важно включить его, даже на этой ранней стадии.) Убедитесь что вы используете расширенный файл .gitignore из Листинга 3.2 чтобы ключ .secret не отображался в вашем репозитории.

# Be sure to restart your server when you modify this file.

# Your secret key is used for verifying the integrity of signed cookies.
# If you change this key, all old signed cookies will become invalid!

# Make sure the secret is at least 30 characters and all random,
# no regular words or you'll be exposed to dictionary attacks.
# You can use `rake secret` to generate a secure secret key.

# Make sure your secret_key_base is kept private
# if you're sharing your code publicly.
require 'securerandom'

def secure_token
  token_file = Rails.root.join('.secret')
  if File.exist?(token_file)
    # Use the existing token.
    File.read(token_file).chomp
  else
    # Generate a new token and store it in token_file.
    token = SecureRandom.hex(64)
    File.write(token_file, token)
    token
  end
end

SampleApp::Application.config.secret_key_base = secure_token
Листинг 3.2. Динамическая генерация секретного токена. config/initializers/secret_token.rb

Затем нам необходимо сконфигурировать Rails для использования RSpec вместо Test::Unit. Это может быть достигнуто с помощью rails generate rspec:install

$ rails generate rspec:install

Если ваша система жалуется на отсутствие JavaScript runtime, посетите execjs страницу на GitHub, где приведен список возможных решений. Я особенно рекомендую установку Node.js.

Все что нам осталось — инициализировать Git репозиторий:3Как и прежде, увеличенный файл из Листинга 1.7 может оказаться более удобным.

$ git init
$ git add .
$ git commit -m "Initial commit"

Как и с первым приложением, я советую обновить README файл (находится в корневой директории приложения) чтобы сделать его более полезным и описательным, как показано в Листинге 3.3.

# Перевод Ruby on Rails Tutorial: пример приложения

Это пример приложения для
[*Ruby on Rails Tutorial*](http://railstutorial.org/)
by [Майкл Хартл](http://michaelhartl.com/).
Листинг 3.3. Улучшенный README файл для примера приложения.

Затем изменим его расширение на markdown и зафиксируем изменения:

$ git mv README.rdoc README.md
$ git commit -am "Improve the README"

Вы можете вспомнить из Раздела 1.3.5 что мы использовали Git команду git commit -a -m "Message", с флагами для "все изменения" (-a) и сообщение (-m). Как показано во второй команде выше, Git также позволяет свернуть два флага в один: git commit -am "Message"

Поскольку мы будем использовать этот пример приложения на протяжении оставшейся части учебника, хорошей идеей будет создание нового репозитория на GitHub отправка туда нашего кода:

$ git remote add origin https://github.com/<username>/sample_app.git
$ git push -u origin master

В результате выполнения мною этого шага вы можете найти код примера приложения на GitHub (от имени пользователя railstutorial и немного другим названием sample_app_rails_4).4https://github.com/railstutorial/sample_app_rails_4

Конечно, мы также можем задеплоить приложение на Heroku даже на этой ранней стадии

$ heroku create
$ git push heroku master
$ heroku run rake db:migrate

(Как было отмечено в Разделе 1.4.1, некоторые читатели сообщали о необходимости прекомпиляции ассетов при помощи команды:

# Это должно быть использовано только если вы не можете задеплоить на Heroku.
$ rake assets:precompile
$ git add .
$ git commit -m "Add precompiled assets for Heroku"
$ git push heroku maste

Шаг прекомпиляции ассетов по идее не нужен и я не смог воспроизвести ситуацию в которой он был бы необходим, но количество получаемых сообщений об ошибках таково что я вынужден упомянуть здесь о решении.)

Я рекомендую регулярно пушить и деплоить ваш пример приложения в процессе чтения учебника:

$ git push
$ git push heroku
$ heroku run rake db:migrate

Это обеспечит вас бэкапами в удаленном (не локальном) хранилище и позволит отловить продакшен-ошибки настолько быстро, насколько это вообще возможно. Если вы столкнетесь с проблемами на Heroku, вам, вероятно, захочется взглянуть на продакшен логи для того чтобы попытаться диагностировать проблему:

$ heroku logs

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

Вадим Обозин
Вадим Обозин

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