What's New in Rails 4?

of 01

What's New in Rails 4?

Now that Rails 4 is out, it's time to take a good look at it. Ruby on Rails 4 does not change anything architecturally, as Rails 3 did, so there are no huge changes here. But as with any major release, there are thousands of little changes under the hood.

  • Ruby on Rails 4 requires Ruby 1.9.3 or higher and prefers Ruby 2.0. This puts the final nail in the coffin for Ruby 1.8.x which, after all these years, was still kind of hanging on. Time to upgrade guys and if you'll want to continue with Rails, you'll have to now. Luckily, upgrading your dev machines with RVM is a breeze.

  • The mass assignment mechanisms have once again changed. The attr_accessible method in the model is gone, and indeed mass assignment in the "traditional" way of feeding unfiltered params to the model is taken out and put into a gem. Instead, you now use the permit and require methods on the params hash to generate hashes that the model will accept. This decouples the model from the user interface more, as well as makes it more flexible and requires you to explicitly state which attributes you want to update. This should (hopefully) end the mass assignment security risk for good while still not getting in the way of controllers.

  • A controversial change to Rails is the turbolink. By default, Rails will no longer generate any normal HTTP links, everything is done with Javascript. The initial page is served normally, but any link clicked on after that will delete all the markup, replace with the markup from the HTTP reply and update the URL displayed in the address bar. At first, this sounds absolutely silly. Why not simply use a normal HTTP link instead of emulating that behavior with Javascript? This method is much faster, the browser doesn't have to make requests to see if the CSS and Javascript files have changed, or make any additional requests at all other than the single request that generated the result. All image caches are still active, it just populates the new page, does its layout magic and the user doesn't know the difference (except potentially snappier response times).

    Is this really a good idea? Time will tell, but thankfully you can turn it off on individual links or any links in a div with the data-no-turbolinks attribute (for example, <a href="/" data-no-turbolinks>Home</a> or removing the turbolinks line from your Gemfile. Though this is very lightweight Javascript that should work on all halfway modern platforms.

  • Rails 4 is thread-safe by default. This should help performance on threaded HTTP servers where multiple requests can be handled by the same Ruby process. This doesn't mean all that much for the typical Rails application, but it does mean that you'll need to ensure all gems you use are thread safe and all your application code keeps its state to itself. So if your application is touching any global variables, or any class variables, then it may run into problems. If another thread accesses the same variable then it could end in crashes or other disastrous results, possibly even data corruption depending on how this data is being used.

  • Streaming is now supported via Rails. HTTP streaming is the process of doling out the response to a request over time, rather than all at once. It's often used for media, such as streaming video, or to provide a real-time output of another program. While streaming, the Rails application can produce output, wait for new data to be generated or just wait a specified amount of time and continue streaming more output.

    To use streaming, simply include the ActionController::Live module in your controller and use response.stream.write to write text or data to the stream. When you're finished, use response.stream.close. This is a small addition, but it opens up all kinds of things as far as live media is concerned.

  • Finders were overhauled, and the old option hashes are gone. Not gone totally, they've been removed to the deprecated finders gem which is included as a dependency on Rails 4 (but won't be on 4.1), but you should stop using them. So, instead of using the naked find method, you should be using the auto-generated find_by_* type methods.