Рельсы 4 стремительно приближаются . В этой статье давайте рассмотрим некоторые из новых функций, которые он предлагает, а также изменения, которые могут повлиять на ваши текущие приложения.
Некоторая бухгалтерия
Дайджесты кэша — это решение Rails 4 для отслеживания изменений в агрессивно кэшированных шаблонах.
В Rails 4 есть несколько конфигурационных и структурных изменений.
Ruby> = 1.9.3
Rails 4 будет поддерживать только Ruby 1.9.3+. Будьте готовы к обновлению, если еще не сделали этого.
Threadsafe по умолчанию
Rails 4 будет поточно-ориентированным по умолчанию, устраняя издержки и улучшая производительность на многопоточных серверах, таких как thin и puma . Вы должны убедиться, что ваше приложение (и его зависимости) являются поточно-ориентированными, что обычно означает избегание глобального состояния (например, класса или глобальных переменных).
Аарон Паттерсон писал и говорил на эту тему. Определенно проверьте это!
Нет больше vendor/plugins
Rails 3 придерживался идеи использования гемов для добавления пользовательских функций в Rails и не одобрял использование плагинов. Rails 4 завершает этот переход, полностью удаляя каталог vendor/plugins
.
Новые каталоги тестирования
Схема именования каталогов по умолчанию более понятна, чем в Rails 3.
Теперь будут созданы следующие каталоги: test/models
, test/helpers
, test/controllers
, test/mailers
и test/integration
.
исполняемые
Каталог script
был удален в пользу нового каталога bin
. Именно здесь будут жить исполняемые файлы вашего приложения и запускать rake rails:update:bin
поместит binstubs bundle
, rake
и rails
каталог bin вашего приложения.
Это изменение может быть полезно при разработке, особенно на машине с несколькими версиями Ruby и гемами. Вы можете использовать bin/rails
вместо bundle exec rails
чтобы убедиться, что вы запускаете свои исполняемые файлы в правильной среде.
Сильные Параметры
Rails 4 решает проблему массового назначения с новым гемом Strong Parameters . Приложение Rails 3 может иметь действие create
подобное следующему примеру:
1
2
3
4
5
6
|
class UsersController < ApplicationController
def create
@user = User.create(params[:user])
# … check validity, redirect, etc.
end
end
|
Вы можете защитить от неожиданного ввода с помощью объявлений в модели:
1
2
3
4
|
class User < ActiveRecord::Base
# Only allow the following attributes to be mass-assigned
attr_accessible :name, :email
end
|
Использование Strong Parameters в Rails 4 перемещает пользовательский ввод в контроллер:
01
02
03
04
05
06
07
08
09
10
|
class UsersController < ApplicationController
def create
@user = User.create(user_params)
# … check validity, redirect, etc.
end
def user_params
params.require(:user).permit(:name, :email)
end
end
|
Как видите, хэш params
в вашем контроллере не является обычным хешем. На самом деле это экземпляр ActionController::Parameters
, который предоставляет методы require
и ActionController::Parameters
.
Метод require
обеспечивает доступность указанного ключа в хэше params
и вызывает исключение ActionController::ParameterMissing
если ключ не существует.
Метод
permit
защищает вас от неожиданного массового назначения.
Вызов User.create(params[:user])
вызывает исключение User.create(params.require(:user).permit(:name, :email))
ActiveModel::ForbiddenAttributesError
, но использование User.create(params.require(:user).permit(:name, :email))
заставляет его работать без жалоб.
Функциональность массового назначения в Rails 3 не только отключена в Rails 4, но и была извлечена в гем , на случай, если вам потребуется эта функциональность.
Turbolinks
По умолчанию Rails 4 будет поточно-ориентированным, устраняя издержки и улучшая производительность.
Спорные новая функция в Rails 4 является Turbolinks , JavaScript плагин разработан , чтобы сделать приложение навигации быстрее в браузере.
В браузерах с поддержкой pushState
нажатие на ссылку вызывает плагин Turbolinks . Он делает запрос Ajax, обновляет URL с помощью pushState
(чтобы ваша кнопка назад pushState
) и использует JavaScript для обновления <title>
и <body>
в DOM. Повышение скорости происходит из-за того, что нет необходимости загружать и обрабатывать ресурсы JavaScript и CSS.
Turbolinks изящно ухудшается для браузеров, которые не поддерживают pushState
. В этих ситуациях ссылки на страницы ведут себя как обычно, вызывая полное обновление страницы.
События и кэш
В приложениях принято ждать полной загрузки страницы перед выполнением любого JavaScript. Например:
1
2
3
|
$(document).ready(/* some function to run */) {
// or event just $(/* some function to run */)
}
|
С Turbolinks события загрузки страницы не будут срабатывать, когда пользователи переходят от «страницы» к «странице», потому что DOM фактически никогда не перезагружается. Поэтому библиотека добавляет новые события, которые вы можете прослушивать, чтобы выполнить любые последующие инициализации, которые могут понадобиться вашему приложению:
-
page:fetch
— начало загрузки страницы с сервера -
page:change
— страница была загружена -
page:load
— страница была загружена с сервера -
page:restore
— страница была загружена из кеша
Событие page:change
всегда срабатывает, когда Turbolinks загружает страницу, за которой следует page:load
или page:restore
, в зависимости от того, была ли загрузка получена с сервера или из кэша.
Потенциальные проблемы
Скоро появится Rails 4, и он внес множество изменений в структуру.
У Turbolinks есть несколько проблем, которые вам, возможно, придется решить:
- Утечки памяти : Turbolinks не очищает и не перезагружает ваш JavaScript при изменении страницы. Вы можете увидеть последствия утечек памяти в своих приложениях, особенно если вы используете много JavaScript.
- Привязки к событиям : вы должны принять во внимание старые браузеры. Убедитесь, что вы слушаете события
page:*
, а такжеDOMContentLoaded
. - Клиентские фреймворки : Turbolinks могут плохо работать с другими клиентскими фреймворками, такими как Backbone, Angular, Knockout, Ember и т. Д.
Не принимая участия
Вы можете отказаться от Turbolinks:
- удаление
turbolinks
из вашего Gemfile, и - удаление строки
//= require turbolinks
изapplication.js
Кэширование
Rails 4 предлагает переработанную стратегию кэширования. Во-первых, кэширование действий и страниц, как вы, возможно, знаете из предыдущих версий Rails, было удалено и извлечено в gems: action и page соответственно.
Русские куклы
Новый ребенок на блоке — русская кукла, или кэширование вложенных фрагментов. Самый простой способ понять эту систему — взглянуть на некоторый код. Предположим, что у вас есть приложение для управления проектами. У вас могут быть следующие модели:
1
2
3
4
5
6
7
|
class Milestone < ActiveRecord::Base
has_many :todos
end
class Todo < ActiveRecord::Base
belongs_to :milestone, :touch => true
end
|
Опция :touch
требуется для правильной работы стратегии кэширования. Если задача добавлена к вехе, нам нужно разбить кеш на вехе, чтобы избежать обслуживания устаревших представлений.
Теперь у нас есть мелкозернистые кэши в наших представлениях. Рассмотрим этот файл в качестве примера ( app/views/milestones/show.html.erb
):
1
2
3
4
5
6
7
8
|
<% cache @milestone do %>
<h1><%= @milestone.name %></h1>
<div class=»description»><%= @milestone.description %></div>
<ul class=»todos»>
<%= render @milestone.todos %>
</ul>
<% end %>
|
И в app/views/todos/_todo.html.erb
:
1
2
3
4
5
6
|
<% cache todo do %>
<li class=»todo»>
<%= todo.description %>
<span class=»status»><%= todo.status %>
</li>
<% end %>
|
Теперь предположим, что у вас есть веха с десятью задачами. Редактирование только одной задачи приводит к разрыву кэша вехи, но при генерации HTML из кэша могут быть получены все части, кроме одной, чтобы сократить время рендеринга.
PATCH теперь новый HTTP-глагол для обновления ресурсов.
Вы тратите время на пространство, так как это приводит к большим потерям в вашем кеше. Но, как указывает DHH , хранилища кеша, такие как Memcached, просто отбрасывают старые данные, чтобы освободить место для новых данных. Так что это не проблема в большинстве случаев.
Кэш Дайджесты
Дайджесты кэша — это решение Rails 4 для отслеживания изменений в агрессивно кэшированных шаблонах. Rails 4 отслеживает шаблоны и их зависимости, а также суффиксирует ключи кеша фрагмента с дайджестом шаблона MD5 (и его зависимостями). Когда вы редактируете один из ваших шаблонов, его ключ кеша получает обновление, и вам не придется вручную создавать версии шаблонов.
Для получения дополнительной информации (и для использования в Rails 3), ознакомьтесь с README для гема дайджестов кэша .
Потоковая передача через ActionController :: Live
Новый ActionController::Live
предоставляет возможность потоковой передачи данных клиентам. Просто включите модуль в контроллер, чтобы приложение могло отправлять произвольные потоковые данные. Вам придется использовать многопоточный сервер, например thin и puma , для потоковой передачи данных; действия от потоковых контроллеров выполняются в отдельном потоке.
Вот пример из документации по Rails 4:
01
02
03
04
05
06
07
08
09
10
11
12
|
class MyController < ActionController::Base
include ActionController::Live
def stream
response.headers[‘Content-Type’] = ‘text/event-stream’
100.times {
response.stream.write «hello world\n»
sleep 1
}
response.stream.close
end
end
|
Как отмечают документы , нужно помнить о трех вещах:
- Вы должны записать любые заголовки, прежде чем вызывать
write
илиclose
в потоке ответов. - Вы должны вызвать
close
в потоке ответов, когда закончите запись данных. - Убедитесь, что ваши действия являются потокобезопасными, так как они будут выполняться в отдельном потоке.
Тонкости и другие вещи
Мы поговорили о «заголовочных» функциях в Rails 4. Но этот выпуск большой и включает в себя ряд небольших изменений, о которых нужно знать.
PATCH
Как описано в блоге Rails , PATCH теперь является HTTP-глаголом для обновления ресурсов.
Это изменение, как правило, будет прозрачным для разработчиков, поскольку запросы PUT будут по-прежнему направляться к действию
update
для маршрутов в стиле RESTful.
Но это изменение, о котором вы должны знать; PUT маршрутизация может измениться в будущем.
Пользовательские типы Flash
Эта небольшая функция может помочь очистить некоторый код. Вы можете зарегистрировать свои собственные типы флэш-памяти для использования в вызовах redirect_to
и в шаблонах. Например:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
# app/controllers/application_controller.rb
class ApplicationController
add_flash_types :error, :catastrophe
end
# app/controllers/things_controller.rb
class ThingsController < ApplicationController
def create
# … create a thing
rescue Error => e
redirect_to some_path, :error => e.message
rescue Catastrophe => e
redirect_to another_path, :catastrophe => e.message
end
end
# app/views/layouts/application.html.erb
<div class=»error»><%= error %></div>
<div class=»catastrophe»><%= catastrophe %></div>
|
Устаревшие Искатели
В Rails 4 устарели хэши опций поиска в старом стиле, а также все методы динамического поиска (за исключением find_by_...
и find_by_...
). Вместо этого вы будете использовать where
:
-
find_all_by_...
можно переписать с помощьюwhere(...)
. -
find_last_by_...
можно переписать, используяwhere(...).last
. -
scoped_by_...
можно переписать с помощьюwhere(...)
. -
find_or_initialize_by_...
можно переписать с помощьюwhere(...).first_or_initialize
. -
find_or_create_by_...
может быть переписан с использованиемfind_or_create_by(...)
илиwhere(...).first_or_create
. -
find_or_create_by_...!
может быть переписан с помощьюfind_or_create_by!(...)
илиwhere(...).first_or_create!
,
Устаревший драгоценный камень поиска будет включен в качестве зависимости в 4.0. и удалено в 4.1. Драгоценный камень, однако, будет вокруг и поддерживается до 5.0.
Проблемы маршрутизации
Проблемы маршрутизации — это попытка высушить ваш config/routes.rb
Основная идея состоит в том, чтобы определить общие подресурсы (например, комментарии) как проблемы и включить их в другие ресурсы / маршруты. Вот очевидный пример:
01
02
03
04
05
06
07
08
09
10
|
concern :commentable do
resources :comments
end
concern :remarkable do
resources :remarks
end
resources :posts, :concerns => :commentable
resources :articles, :concerns => [:commentable, :remarkable] # can include several
|
Вышесказанное эквивалентно следующему коду Rails 3:
1
2
3
4
5
6
7
8
|
resources :posts do
resources :comments
end
resources :articles do
resources :comments
resources :remarks
end
|
Лично я не уверен, что это добавляет много ценности; возможно, это имеет смысл для больших приложений с сотнями маршрутов.
Переименованные обратные вызовы
Обратные вызовы действий в контроллерах были переименованы из *_filter
в *_action
. Например:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
class UsersController < ApplicationController
before_action :set_user, :except => [:index, :new, :create}
before_action :require_the_president, :only => [:fire_the_missiles]
private
def set_user
@user = somehow_find_and_set_the_user(params[:id])
end
def require_the_president
@user.is_the_president?
end
end
|
Старые *_filter
вызовы *_filter
прежнему работают и не являются устаревшими; так что вы можете использовать их, если хотите. DHH причина изменения была:
«Чтобы избежать ошибочного представления о том, что эти обратные вызовы подходят только для преобразования или остановки ответа. В новом стиле более привлекательным является их использование по назначению, например установка общих иваров для представлений».
Завершение
Скоро появится Rails 4, принесший с собой множество изменений. Я надеюсь, что эта статья дала вам представление о том, чего ожидать, и, возможно, отправную точку для изучения того, что может предложить эта новая версия.
Если вы действительно хотите углубиться в глубокий конец, ознакомьтесь с нашим курсом Tuts + Premium по Rails 4 !