Вышел релиз Rails 4.1. Некоторые тонкости переезда

image8 апреля в официальном блоге Ruby on Rails появилось сообщение об официальном выходе Rails 4.1. Весь функционал уместился в 5200 коммитов.На хабре уже был обзор бета версии. Также можно почитать Release notes и A Guide for Upgrading Ruby on Rails.

В статье я бы хотел остановиться на некоторых тонкостях и деталях того, что под капотом.

Active Record Enums class Conversation < ActiveRecord::Base enum status: [ :active, :archived ] end

# conversation.update! status: 0 conversation.active! conversation.active? # => true conversation.status # => «active»

# conversation.update! status: 1 conversation.archived! conversation.archived? # => true conversation.status # => «archived»

# conversation.update! status: 1 conversation.status = «archived»

# conversation.update! status: nil conversation.status = nil conversation.status.nil? # => true conversation.status # => nil Теперь мы имеем вот такой синтаксис для перечислений. Очень вкусно, очень удобно, но важно понимать несколько моментов. 1. Перечисление сохраняется как целое число в базе, но может быть получено по имени. (Enum values map to integers in the database, but can be queried by name).Вот так будет выглядеть миграция примера выше:

create_table: conversations do |t| t.column: status, : integer end При этом в SQL-запросах тоже придется использовать целые числа: where ('status <>? OR status <>?', 0, 1)where ('status <>? OR status <>?', STATUS[: resolved], STATUS[: rejected])Обратите внимание, что в даном случае STATUS — это константа класса, добавляемая макросом автоматически при создании перечисления.2. Перечисление не использует ENUM тип, реализованный в некоторых в базах данных. Как следствие — нельзя изменять порядок значений в перечислении после создания записей в базе. Это приведет к путанице и конфликтам. Нельзя также просто удалить ненужное значение. Для этого соответствие между строковыми и численными значением должно быть задано явно.

class Bug < ActiveRecord::Base enum status: { new: 0, #removed status with id=1 in_progress: 2, resolved: 3, rejected: 4, reopened: 5 } end Получить этот хэш можно через Bug.statuses3. Есть ограничения по именам значений перечисления.Нельзя называть значения enum'ов именами существующих scopes, ассоциаций (что понятно) и уже существующих перечислений в рамках одной модели (что неочевидно). Например:

class Bug < ActiveRecord::Base enum status: [ :new, :closed ] enum code_review_status: [ :new, :finished ] # Так делать нельзя end Новое поведение Default scopes Теперь default_scope по умолчанию влияет на все остальные scopes, если явно не указано обратное. class User < ActiveRecord::Base default_scope { where state: 'pending' } scope :active, -> { where state: 'active' } scope: inactive, → { where state: 'inactive' } end Теперь User.active будет эквивалентно User.where (state: 'pending').where (state: 'active'). Т.е. по умолчанию все scopes цепляются (chains) к default_scope.Чтобы избежать этого нужно явно «отцепить» scope от default_scope с помощью unscope, except, rewhere: class User < ActiveRecord::Base default_scope { where state: 'pending' } scope :active, -> { unscope (where: : state).where (state: 'active') } scope: inactive, → { rewhere state: 'inactive' } end Расширенная CSRF защита. Теперь по умолчанию CSRF защита включена и на get запросах с форматом .js.Для честного разработчика есть два прикладных следствия из этого.Во-первых, валятся все тесты, которые проверяли формирования правильного JS кода. Бороться с этим несложно.Вместоpost: create, format: : jsПишемxhr: post, : create, format: : jsА во-вторых, если все-таки надо разрешить сторонним сайтам запрашивать js код, то надо явно указать это, добавив фильтр в контроллер: skip_before_filter: verify_authenticity_token, only: [: stats, : visitor] Ну и в каждом action надо добавить в заголовок ответа: response.headers['Access-Control-Allow-Origin'] = '*' Либо вместо звездочки указать имя сайта, которому разрешен доступ.Пока это всё, с чем пришлось повозиться самому. Кончено же, функционал нового релиза Rails 4.1 гораздо шире. Но там как раз все вроде понятно, про это уже писали, к тому же, описание новой функциональности как всегда на высоте.Но на всякий случай приведу список остальных Major Features: Добавлен прелоадер Spring по умолчанию в новые проекты Добавлен файл config/secrets.yml вместе с функционалом для хранения секретов приложений. Action Pack Variants — возможность использования разных ответов для различных типов устройств (tablet, desktop, phone, etc.) Action Mailer Previews — интеграция gem’а MailView в Rails — удобная работа с шаблонами писем. Message Verifiers — обмен и проверка подлинности важных сообщений. Module#concerning — удобное разделение ответственности между классами (честно говоря, я пока не нахожу ситуации, когда бы мне понадобилась эта функциональность) Официально прекращена поддержка MySQL 4.1 (это если еще кто-то, кроме меня вынужден работать с этим раритетом). В реальности пока еще работает.

© Habrahabr.ru