Рельсы 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 !