Climbing up to Rails 5.0

UPGRADING TO RAILS 5.0 (ANTIPATTERN: STAYING ON AN UNSUPPORTED VERSION OF RAILS)

In many ways, while Rails 5 was a visionary step forward for Rails, it is largely an extension of Rails 4.2. The primary thing to note upfront is ActionCable — a fancy implementation of WebSockets, a protocol that keeps the connections between your client and server alive. Unlike normal web requests (in which a request from the client gets a response from the server fairly immediately— ideally within 200ms), these client-server interactions keep the connection open for the server to send communication down to the client (or “back”). The mechanism used for this is called “publish-subscribe.” This is ideal for real-time messaging, in which users send chat messages or the server pushes events to the user’s screen in real time.

Unfortunately ActionCable has not been largely adopted. This is because the new class of RTM (real-time messaging) apps built after 2016 were predominately created in the Node JS world. For this reason, ActionCable gets only an honorable mention in this guide. I will explore ActionCable in a future lesson.

In the meantime, let’s take a quick look a few more things to note when upgrading an app from Rails 4.2 to Rails 5.0.

As always with upgrades, fix your deprecation warnings in Rails 4.2. All you have to do is pay attention to your Rails console output as you are developing. They will contain lots of warnings telling you what will be removed in Rails 5.0. Remember, you do this while you are still in Rails 4.2!

Deprecate, Depreciate, and Removed

And while I’m on the subject, a quick point of the words themselves.

deprecate (dep – ri – kāt, with three syllables) is when a feature in a programming language (like Rails) will be removed in the future, and the fact of its impending removal is cause for paying attention. In other words, a feature becomes deprecated in Rails 4.2 will start showing deprecation warnings in Rails 4.2. The feature still works, however, until Rails 5, when it is removed from Rails. (They are not the same: Deprecate means “still in there but going to be removed” and removed means “it’s gone now.”)

Finally, an important thing to note when learning—an easy slip-up for many non-native English speakers— is another English word: depreciate. Just one letter off, if you add an “i” you have a different word— di- ‘prē- shē- āt is a four syllable word and it means “to lesson in value.” It can refer to an automobile, as in: “I purchased the car for $4000 but because it has depreciated over time, it will now sell for only $2000.” (In tax accounting “depreciate” is a special term that refers to calculating a value as lessening over time.) Deprecate is what happens to features in programming languages that are going to be removed. (That’s probably the word you want in this context.) Depreciate is what happens when you are calculating your taxes. They are not the same word!

rails replaces rake

In the past you used to run rake on the command line. Running rake is now a thing of the past, instead, all rake tasks are available by running rails.

API Only Rails 5

You can now make a new app with --api. This will skip all the annoying view rendering and all the other heavy stuff. Perfect for when you just want Rails as an API. Rejoice!

Action Cable

As discussed above, ActionCable is ideal for real-time messaging and chat apps.

Ruby 2.2 Required for Rails 5

You now need Ruby 2.2 to run Rails 5.

An optional belongs_to

Depending on your schema and point of view, an object belongs to another object either always or sometimes. That is, an object can belong to something (remember, belongs_to means the foreign key exists on the table with the belongs_to) but the question is: is the presence of that something required?

Take, for example, a Course (like a class you take in an academic setting) and Lecture (a specific day when the professor gives a single lecture). It would be impossible (in our theoretical system) for the lecture to exist outside of the context of a Course. So a Lecture belongs_to a Course.

Class Lecture < ApplicationRecord

belongs_to :course

end

Starting with Rails 5, the default behavior is for the Lecture to be invalid (that is, you won’t be able to save it) if it does not have a course_id set (that is, if it is missing a course). However, there’s a way to leave the belongs_to but remove the validation.

Let’s take a different example of Listing (a property going up for sale) and Agent (a real estate agent who will represent that property). Because the listing will be reprinted by one and only one agent, we’ll specify that a Listing belongs_to an Agent (in the real world I might not recommend implementing this in this fashion but for the purpose of this example it works).

However, we want to be able to put Listings into our database before they are assigned to an Agent, and then assign them to an Agent later down the road. In this case, Rails 5 gives us the option to use

belongs_to :agent, optional: true

(Note that actually this is only really available in Rails 5.2 as some issues exist regarding this behavior in early the version of Rails 5.)

ActiveRecord Attributes

ActiveRecord gets some funky changes under the hood. In short,

  • You can override the type that Active Record detects.
  • Because of some detachment under the hood, a default can also be provided. You set the defaults at the database level, when creating your migration. Rails will now automatically pick them up from the database defaults even when creating new objects (that is, before your object is actually saved back to the database).[TODO: VERIFY IF THIS STARTS IN RAILS 5.0 or 5.2]
  • In ActiveRecord, attributes do not need to be backed by a database column

Test Running

We get a new test runner to enhance the capabilities of running tests from Rails. To use this test runner simply type bin/rails test.

Attributes API

The Attributes API was introduced in Rails 5 but did not get much adoption.

Turbolinks 5 (or “3” dependin gon how you are counting)

New the version of Turbolinks in Rails 5 solves one of the major headaches of Rails. Many apps were slow because they reloaded the full page from server. This new Turbolinks reloads only the contents of the body. It doesn’t reload the whole page. It also allows you to specify which elements to replace through partials.

REMOVALS

You can no longer return false inside of a filter chain

Before Rails 4, the way to invoke methods in controllers before you main controller action run was to use a filter. For example, before_filter :xyz, your controller would call the xyz method before all of the controller’s actions. This was great for authentication and “setup” stuff, and sometimes you wanted to “halt” the filter chain. That is, you wanted to tell Rails not to do the controller action but instead halt because the user, for example, doesn’t have access. In this case, you used to return false from the method to stop the filter chain.

This is no longer true. First off, you should change all *_filter callbacks use the new syntax *_action. Just replace _filter with _action. If you were returning false, you should now raise an explicit exception. There’s a great controller pattern for gracefully handling access control and authorization exceptions at the controller— I will explore this in a future lecture.

• Deprecated *_via_redirect integration test methods. Use follow_redirect! manually after the request call for the same behavior. 

Deprecated redirect_to :back in favor of redirect_back, which accepts a required fallback_location argument

Controller actions without an explicit render call and with no corresponding templates will render head :no_content implicitly instead of raising an error

Discarded flash messages get removed before storing into session.

• In Action Mailer, Removed deprecated deliver and deliver! methods (switch all of these to deliver_now and deliver_later)

Params (that is, the params coming into the controller in the web request) aren’t a hash. Before Rails 5, params were a straight-up Ruby hash. Now they are a special object that will “beep” at you (give you an “unpermitted parameters” warning) if you try to access the parameters inappropriately. (That is, without using strong parameters.) They don’t actually beep (I was kidding)… what happens is your controller action gracefully passes through as normal but you will see an “Unpermitted Attributes Error” in your Rails log that will tell you the parameters that were passed that weren’t allowed by strong params.

• Like controller testing? Rails controller testing was formally extracted from Rails core and to continue to do controller testing you now use the gem rails-controller-testing.

Ok tomorrow we’ll take a look at Rails 5.1. I hope you’ve enjoyed this upgrading session. Be sure to Like and Follow for more!