- PVSM.RU - https://www.pvsm.ru -
8 апреля в официальном блоге Ruby on Rails появилось [1] сообщение об официальном выходе Rails 4.1. Весь функционал уместился в 5200 коммитов.
На хабре уже был обзор [2] бета версии. Также можно почитать Release notes [3] и A Guide for Upgrading Ruby on Rails [4].
В статье я бы хотел остановиться на некоторых тонкостях и деталях того, что под капотом.
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.statuses
3. Есть ограничения по именам значений перечисления.
Нельзя называть значения enum'ов именами существующих scopes, ассоциаций (что понятно) и уже существующих перечислений в рамках одной модели (что неочевидно). Например:
class Bug < ActiveRecord::Base
enum status: [ :new, :closed ]
enum code_review_status: [ :new, :finished ] # Так делать нельзя
end
Теперь 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 защита включена и на 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'] = '*'
Либо вместо звездочки указать имя сайта, которому разрешен доступ.
config/secrets.yml
вместе с функционалом для хранения секретов приложений.Официально прекращена поддержка MySQL 4.1 (это если еще кто-то, кроме меня вынужден работать с этим раритетом). В реальности пока еще работает.
Автор: k2m30
Источник [5]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/news/58837
Ссылки в тексте:
[1] появилось: http://weblog.rubyonrails.org/2014/4/8/Rails-4-1/
[2] обзор: http://habrahabr.ru/post/207172/
[3] Release notes: http://edgeguides.rubyonrails.org/4_1_release_notes.html
[4] A Guide for Upgrading Ruby on Rails: http://edgeguides.rubyonrails.org/upgrading_ruby_on_rails.html#upgrading-from-rails-4-0-to-rails-4-1
[5] Источник: http://habrahabr.ru/post/219175/
Нажмите здесь для печати.