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