📜 ⬆️ ⬇️

The release of Rails 4.1 has been released. Some subtleties of moving

image
On April 8, the official Ruby on Rails blog post reported the official release of Rails 4.1. All functionality fit in 5200 commits.

On Habré was already a review of the beta version. You can also read Release Notes and A Guide for Upgrading Ruby on Rails .

In the article I would like to highlight some of the subtleties and details of what is under the hood.

')

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 

Now we have this syntax for enums. Very tasty, very convenient, but it is important to understand a few points.

1. The enumeration is stored as an integer in the database, but can be obtained by name. (Enum values ​​map to integers in the database, but can be queried by name).
This is what the migration of the example above will look like:
 create_table :conversations do |t| t.column :status, :integer end 

In this case, in SQL queries, you will also have to use integers:
where('status <> ? OR status <> ?', 0, 1)
where('status <> ? OR status <> ?', STATUS[:resolved], STATUS[:rejected])
Note that in this case, STATUS is a class constant that is automatically added by the macro when an enumeration is created.

2. The enumeration does not use the ENUM type implemented in some databases. As a result, you cannot change the order of the values ​​in the enumeration after creating records in the database. This will lead to confusion and conflict. You also can’t just delete an unnecessary value. For this, the correspondence between the string and numeric values ​​must be specified explicitly.
 class Bug < ActiveRecord::Base enum status: { new: 0, #removed status with id=1 in_progress: 2, resolved: 3, rejected: 4, reopened: 5 } end 

You can get this hash through Bug.statuses

3. There are restrictions on the names of enumeration values.
You cannot call the enum values ​​by the names of existing scopes, associations (which is understandable) and already existing enumerations within the same model (which is not obvious). For example:
 class Bug < ActiveRecord::Base enum status: [ :new, :closed ] enum code_review_status: [ :new, :finished ] #    end 


New behavior Default scopes


Now the default_scope affects all other scopes by default, unless explicitly stated otherwise.
 class User < ActiveRecord::Base default_scope { where state: 'pending' } scope :active, -> { where state: 'active' } scope :inactive, -> { where state: 'inactive' } end 

Now User.active will be equivalent to User.where(state: 'pending').where(state: 'active') . Those. by default, all scopes chains (chains) to default_scope.
To avoid this, you need to explicitly “unhook” the scope from default_scope with 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 


Extended CSRF protection.


Now, by default, CSRF protection is enabled on get requests with the .js format.
For an honest developer, there are two application implications of this.
Firstly, all the tests that checked the formation of the correct JS code fall down. To fight this is easy.
Instead
post :create, format: :js
We write
xhr :post, :create, format: :js
And secondly, if you still need to allow third-party sites to request js code, then you must explicitly specify this by adding a filter to the controller:
 skip_before_filter :verify_authenticity_token, only: [:stats, :visitor] 

Well, in each action you need to add to the response header:
 response.headers['Access-Control-Allow-Origin'] = '*' 

Or, instead of an asterisk, specify the name of the site that is allowed access.



While this is all that had to tinker with myself. Of course, the functionality of the new release of Rails 4.1 is much broader. But there everything seems to be clear, they have already written about it, moreover, the description of the new functionality, as always, is at its best.
But just in case I will give a list of the rest of Major Features:

Officially, MySQL Server 4.1 support has been discontinued (this is if someone else besides me is forced to work with this rare book). In reality, it still works.

Source: https://habr.com/ru/post/219175/


All Articles