📜 ⬆️ ⬇️

What's new in Rails 4

The fourth version of the Ruby on Rails framework is just around the corner. Although there is no official release date yet, many expect a release candidate at the beginning of this year.
This version of the framework has been under development for a year now and represents many changes in the internal architecture. The framework has evolved and acquired a more modular format, most of the innovations are scattered across individual jamms, in order to keep the main code clean. Thus, the outdated functionality can not be officially supported, but used if such a need arises.

While writing these lines, Engine Yard does not yet officially support Rails 4 in our cloud products. However, if you want to try them out, you can of course. However, be careful - some features, especially live streaming, most likely will not work.

If you encounter difficulties when trying to deploy applications on Rails 4, then you need to register them as feature requests , not as a bug, since we have not finished integrating Rails 4 into our products.

')

Notable changes in Rails 4


Many things have changed or been reworked in Rails 4, and several new features have been added. Although this article is not exhaustive, we will try to explain some of the most recent and significant innovations.

Ruby 1.9.3 Minimum

One of the most notable changes in Rails 4 that all developers should pay attention to is that Ruby 1.9.3 is now the minimum requirement. Support for 1.8.7 has been completely discontinued, but given that most of us use 1.9.3, there is no reason to worry about support for 1.9.2. In fact, this commit from Jose Valim bluntly tells the user that Rails 4 requires Ruby 1.9.3+ and interrupts work immediately if RUBY_VERSION <1.9.3.
What does this mean to you? First, if you are using 1.8.7 or Ruby Enterprise Edition (which is actually 1.8.7 with little performance tuning options), you would need to upgrade anyway. Upgrading from 1.8.7 to 1.9.3 can be both painless and quite complicated - it all depends on the program, its dependencies, and what could become outdated between these two releases. Make sure you have good code coverage, switch the interpreter in development mode to 1.9.3 (this is extremely simple with RVM ), and run the tests. If you are interested in additional tips on how to go from 1.8 to 1.9, read this article by my colleague from Engine Yard, Anthony Accomazzo.
In any case, I highly recommend everyone to use only the latest stable versions of the interpreter with the latest updates available to achieve the best performance and security level.

No more vendor / plugins

The vendor / plugins folder is not in Rails 4. Instead, you need to use a Bundler with the desired path or Git dependency.
Many obsolete items have moved into separate jams.

Hash-based and dynamic finder methods

You may remember that in recent versions of Rails, warnings against the “old” ActiveRecord query syntax were constantly issued. For example:

User.find(:first, :conditions => { … }) 

This syntax is no longer supported in Rails 4. To add this functionality to your program, you will have to install the following activerecord-deprecated_finders gem jam: github.com/rails/activerecord-deprecated_finders

ActiveRecord :: SessionStore

Storing sessions in a database is an interesting feature of many useful programs, especially for confidential information, but, in most cases, it is not as efficient as using a simple cookie. So, ActiveRecord :: SessionStore is not in Rails 4. Use the activerecord-session_store jam to return this functionality: github.com/rails/activerecord-session_store .
If to be meticulous, storing confidential information in a cookie is a bad idea for many reasons. Lack of encryption (or weak encryption) is just one of them. The best solution for storing such information would be to use the database (protected by the network access level and the application itself), and then simply refer to the ID in the session object. I mean, instead of installing a whole object in a session or even meta information about an object, you can save the object in the database and simply refer to its ID within the user's session (and put its meta information in memcached or PostgreSQL hstore).

ActiveResource

ActiveResource is an ORM (Object-Relational Mapping) for REST-based services. It has been removed from Rails 4 and will no longer go out with it. Guillermo Iguaran told the Yeti Media blog that the motivation for this was that his support did not highlight the necessary amount of love and attention of the core development team that it deserves . After the ActiveResource was separated, they were taken up by a separate development team led by Jeremy Kemper . Since the separation, many new features have been added, so for all ActiveResource fans, this should have been more good news. It also became useful for those who would like to use the ActiveResource functionality without having to use all of the Rails for this. To use ActiveResource, simply enable the 'activeresource' jam: github.com/rails/activeresource .

Rails Observers, Caching Pages and Actions

The ability to cache pages and actions has been removed from Rails 4 in favor of caching codenamed “Matryoshka” (Russian Doll). DHH (David Heinemeier Hansson) has a jam that explains how such caching works (see github.com/rails/cache_digests for more information).
Given the lack of caching pages and actions, the need for browsers is almost absent. In many cases, these browsers are used to expire the cache, which, due to the caching scheme in Rails4, is not so necessary. Also, observers are often abused, using them as a dump for persistent operations (persistence operations), where callback would be much more appropriate. So Rails 4 will come out without caching pages, actions, and browsers.
To include them in the program, take a look at:

github.com/rails/actionpack-action_caching
github.com/rails/actionpack-page_caching
github.com/rails/rails-observers

Dalli instead of memcache-client

Dalli is now used with memcached instead of memcache client. This innovation will be approved by many developers, as Dalli is much quicker than the memcache client, and allows the use of parallelism (multithreading) - a topic that is of great concern in the ruby ​​community. To use this functionality, you need to add the “dalli” jam to your Gemfile if it is still missing there and specify mem_cache_store as your cache store.

New Default Test Locations

Newcomers to Rails and TDD (development through testing) are often confused by the default settings and names. “Models” correspond to “units”, to tests of “controllers” - “functional” tests, etc. In Rails 4, this will change for more clarity. The default test location names will be more similar to the rspec convention names for Rails tests:

app / models -> test / models (was test / units)
app / helpers -> test / helpers (was test / units / helpers)
app / controllers -> test / controllers (was test / functional)
app / mailers -> test / mailers (was test / functional)

If you have the mood, and you want to read about the names of the tests and their purpose, then you definitely need to read or participate in this discussion . At the beginning, the commit was intended to rename the “integration” test (test / integration) into the “acceptance” test. Although the rest of this request was accepted positively, it was this change that caused a lot of discussion about what is the “acceptance” test and what isn't. In the end, the author of the blowmage commit decided to leave the name as it is, so as not to delay the approval of the commit, which led to the approval of several key Rails developers.

Verb PATCH

Rails used the “PUT” HTTP method to modify existing resources for a long time. However, the specification of HTTP semantics implies a complete resource descriptor under PUT. In other words, PUT, semantically speaking, must contain a complete presentation of the object that needs to be changed. Consequently, on the technical side, we did this “wrong” for quite a long time, sending pieces of the object that needs to be changed when we made RESTful updates using PUT.
That is why this functionality has been changed in Rails 4, and the verb PATCH must be used. As the name itself tells us, PATCH is intended to send pieces of information about an object on a server without its full description. This more closely matches the HTTP semantics, as described in RFC 5789 .
As with all RESTful forms in Rails, a hidden “_method” field will be generated indicating that the “PATCH” method will be used instead of “PUT”. And as expected, the routing will associate the PATCH method with the “update” action in the controller.
In order to maintain backward compatibility, the former PUT method will also be directed to “update” in Rails 4.0 so that existing APIs can continue their normal work.
On the Rails blog, you can learn more about the PATCH method . This is a great change, and what was thought of backward compatibility will make it easier for developers to update.

Threadsafe default

Ruby developers have long sought to achieve true multi-threading without using GIL , and the authors of Rails understand that MRI is not the only way to launch applications into production. Multithreading servers and applications can significantly increase performance by using shared memory segments and allows simultaneous execution of code.
However, the standard interpretations of Ruby, known as “MRI”, are not truly multi-threaded. It can execute code at the same time if one thread is waiting for input / output, which can allow the main C libraries to execute code at the same time, but the ruby ​​code itself is still executed sequentially due to the presence of GIL.
In Rails, it has long been possible to run code in a multi-threaded manner, but this functionality was not enabled by default and this will be changed in Rails4. This is not such a big change, considering that you can turn on multithreading in most Rails applications right now by changing the settings and restarting the threadsafe server. However, it is worth highlighting for the reason that the Ruby community is becoming more and more aware of the need to simultaneously execute code.
Aaron Patterson discusses config.threadsafe! in more detail in the following article:
tenderlovemaking.com/2012/06/18/removing-config-threadsafe.html

Postgres H-Store

ActiveRecord in Rails 4 will support the PostgreSQL hstore extension. This database extension allows you to create a new data type in the PostgreSQL columns, which will be called 'hstore', which is a string-only hash. For most intents and purposes, this is similar to the serialization of data in a text column, but the fact that it is now a native data type gives us a solid performance boost and the ability to send direct requests to this data type. This means that your application will have a partially non-schematic database without having to use MongoDB, CouchDB, Riak, or another non-schematic datastore.
The hstore extension, although not a full-scale non-schematic solution, its integration into Rails will be an excellent complement for many applications. There are situations where most of your data is normalized for a specific model, but some information needs to be referenced on the fly. This is where the hstore can truly manifest itself.

Let's give a simple example. Let's say your application needs to define new key / value pairs on the fly — define an object scheme that will be different for different users. Maybe it will be a certain type of form in the CMS. The doctor's reception may want to find out information about the patient, and the event manager needs completely different information. In the past, this was solved by serialization, but thanks to hstore, we have a native way for this, which makes it easier to create a query.
You can start using hstore in PostgreSQL using activerecord-postgres-hstore jam. Ryan Bates created a podcast on this topic, where he explains very well how it works and shows many examples of using and creating queries. You can also learn more about hstore by reading the official PostgreSQL documentation . I would like to note that you can use hstore on Engine Yard using PostgreSQL 9.1+ as your database environment. To do this, you can use the created Chef scripts in the postgresql9-extensions section on GitHub.

Array, MACADDR, INET, CIDR

Since we are talking about new data types supported by PostgreSQL and Rails, it is worth noting that ActiveRecord along with Rails 4 will support the following data types in PostgreSQL: Array, MACADDR, INET and CIDR . Although they are usually stored as strings in most databases, PostgreSQL provides support for native data types for each of them, and ActiveRecord can use this.
The INET and CIDR data types will be converted to IPAddr instances, the arrays will be arrays, and the MAC addresses of the requests will be returned in rows.

Live streaming

Aaron Patterson introduced new functionality in Rails 4, called Live Streaming . This actually allows you to broadcast content to the browser of connected users directly from the server using Server-Sent Events. And the fact that the browser is crucial for this process should hint to you about an obvious problem: Internet Explorer does not yet support this. This can be fixed in future versions of IE, but at the moment live streaming does not work in Microsoft's browser.
Live Streaming in Rails 4 also opens up many interesting possibilities for your application. This will be most useful for applications that use real-time information: stock reports and financial applications, games, etc.
Engine Yard does not yet support live streaming for a number of reasons. We have two web servers to choose from: Unicorn and Passenger. None of them support this yet. Passenger 4 Enterprise, currently being developed by Phusion , will support live streaming in Rails, and we will integrate Passenger 4 into our stack as soon as it reaches release status.
By this we do not want to say that Live Streaming is not available from Engine Yard, it just will not work out-of-the-box, and requires additional configuration. We plan to change this by adding the ability to use other application servers. For example, Puma is already available as Early Access, just like Rubinius.

Cache Digests (aka Russian Doll Caching)

ache digest jam automatically adds a digital signature to each fragment cached in your application.
For example, your application caches Authors and Posts:
 <b id="internal-source-marker_0.9843547998461872">class Author < ActiveRecord::Base has_many :posts end class Post < ActiveRecord::Base belongs_to :author, touch: true end</b> 

(I want to note that adding touch: true to the belongs_to association is extremely important, as it also forces the updated_at from Author to change when any author's posts are updated)
Normally you would fragment the cache like this:
 <!-- app/views/authors/show.html.erb --> <% cache ['v1', @author] do %> <h1><%= @author.name %>'s posts:</h1> <%= render @author.posts %> <% end %> <!-- app/views/posts/_post.html.erb --> <% cache ['v1', post] do %> <div><%= link_to post.title, post %></div> <% end %> 

The problem is that you need to update the keys inside the array every time you want to change the cache fragment. Thanks to the “cache digest” in Rails 4, you can simply simply omit the array and Rails will automatically generate an MD5 checksum for the cache. When a file changes, the checksum changes at the same time, resulting in a new “cache digest”.
All of the above can be demonstrated as follows:
 <!-- app/views/authors/show.html.erb --> <% cache @author do %> <h1><%= @author.name %>'s posts:</h1> <%= render @author.posts %> <% end %> <!-- app/views/posts/_post.html.erb --> <% cache post do %> <div><%= link_to post.title, post %></div> <% end %> 

Ryan Bates explains this in more detail in his (free) screencast , and you can already use this functionality in a Rails 3.2 application using jams cache_digests .

Security


Rails has always tried to follow the security market news and this release is no exception. However, in order to take advantage of the latest security enhancements and protect yourself and your application, especially when the next vulnerability was discovered, fixed and disclosed, you need to constantly ensure that your Rails application is updated in a timely manner.
We advise you to subscribe to the Rails Security newsletter (which comes in extremely rarely) and monitor vulnerabilities, update yourself and test your deployment in the debugging environment every time after publishing a new vulnerability. Otherwise, you make yourself an excellent target for another script kiddie or bot, walking around the network with a database of known vulnerabilities.

Mass Assignment Protection in Controller

Personally, I am glad that mass assignment protection has been transferred to the controller. This can be done simply by adding object attributes to the black or white list inside the controller. Take a look at a simple example.
Let's say you create a small web application to accept recipes (culinary). Anyone who creates a recipe becomes known as “chef” and the recipe has a name, ingredients, and description. For the sake of efficiency, we will assume that the issues of authorization and authentication have already been resolved.
 <b id="internal-source-marker_0.9843547998461872">class RecipesController < ApplicationController def create @recipe = Recipe.new(recipe_params) @recipe.chef = current_user # explicitly assign it to the right user if @recipe.valid? and @recipe.save redirect_to @recipe, :flash => { :notice => “Your recipe was added to the cookbook. Mmmm, tasty!” } else render :action => :new end end private def recipe_params params.require(:recipe).permit(:name, :ingredients, :directions) end</b> 

Using this new way of protecting mass assignment, we tell Recipe.new to accept the hash, which the recipe_params method has returned to us, which is the controller's private method. This method separates all unnecessary, which is not allowed by “recipe” parameters. If I wanted to send the following to this controller (represented by the hash):
{name: “Texas Chili”, ingredients: “hot stuff”, chef_id: “123”}
The “chef_id” parameter would be removed by the recipe_params method, because it is not allowed, and then the “sanitized” hash would be passed to Recipe.new. This would prevent the arbitrary assignment of a Recipe object to any “chef” (author) that the attacker would select.
This is a solid change compared to how mass assignment was processed in previous versions of Rails. Instead of pushing these problems into the model, they are now solved inside the controller. This can be somewhat controversial for a number of reasons.
I remember that I spoke with one of the participants on Austin Web Bash about the differences, where the responsibility of the object’s behavior lies. According to the theory of purism, it might be possible to send any information to an object and believe that the object itself knows what to do with it. This is how mass assignment protection worked in previous versions of Rails with its attr_accessible / attr_protected. You could transfer any information to the object (tests, live production data via HTTP, etc.) and the object was responsible for its processing.
However, it is a double-edged sword. Rails is a framework for web applications. This means that, in fact, information is fed from two channels: the user and the developer. The developer would be worth believing, but not the user. Since the only place of attack from the user is the controller, this would be a logical place to protect the information, instead of doing it within the model itself. In most projects, you will encounter situations that require access through the console or manipulation of information (the same migration). A set of 'object.method = "foo" hands for different specific properties each time it is needed is a waste of time, turns you into a zombie and kills productivity. With mass assignment protection in the model, this is what awaits you. Even in the case of software migrations and tests, there is still a chance of unforeseen problems in the development of testing due to mass assignment of protection at the model level, even if you manipulate information in the backend in a safe way. By moving these tasks to the controller, we get rid of this problem and at the same time keep the user input clean.
In essence, this is a choice: either more flexible operations with data, monitoring the purity of input using a controller, or less flexible, but with preserving the desired design of the object. If you still want to use attr_protected / accessible, use the protected_attributes jam in your Rails 4 application.
If you want to start using protection at the controller level, take a look at the strong_parameters jam, compatible with Rails 3.2.x.

Default headers

In Rails 4, an option will be included with which you can specify default headers that will be returned with each response from your application. If the browser at the other end supports such headers, this will increase the level of security for the end user to work with your application.
In Rails 4, the following headers will be set by default on every response:
 config.action_dispatch.default_headers = { 'X-Frame-Options' => 'SAMEORIGIN', 'X-XSS-Protection' => '1; mode=block', 'X-Content-Type-Options' => 'nosniff' } 

. — edge guide on security .
. - , , -. , .

Encrypted Cookies

cookies Rails 4. , session_store 'encrypted_cookie_store'. session store cookies , , . .
, cookies. / SHA, , GPU CUDA , cookie , SHA , , bcrypt. , . , .
, cookies , cookies/ Rails 4 .

Rails 4?


, , , Rails 4.0. 4.1.


Rails 4 API, Sidekiq / Resque . , , “”. Rafael Franca , Rails 4, , .

ActionMailer

API c , ActionMailer , , API.

where.like where.not_like

'not_like' , , Book.where.not_like(title: “%Java%”), ActiveRecord. DHH , , , , . , , , ActiveRecord. DSL “greater_than_or_equal”, Ruby, LIKE - .


Rails 4 , , . Rails 4, , .
, Rails 2.x, Rails 2.3.15 ( ), Rails 3.2. , , , , 3.2 . , , ( ) .
, 3.2 , Rails 4 . cookie store mass assignment, ( ).
, Rails 4 , . , , , .
:

blog.remarkablelabs.com/2012/11/rails-4-countdown-to-2013
blog.wyeworks.com/2012/11/13/rails-4-compilation-links
weblog.rubyonrails.org/2012/11/21/the-people-behind-rails-4
edgeguides.rubyonrails.org/4_0_release_notes.html
rubyrogues.com/081-rr-rails-4-with-aaron-patterson
Rails 4 Whirlwind Tour: vimeo.com/51181496

.
1 , 2 .
— J. Austin Hughey
—

, . .
. — e. !

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


All Articles