Lots of people have asked me, since the release of Rails 5, a couple of things:
1. Will there ever be a Rails 5 in Action? (if there is, I won’t be writing it)
and, more importantly:
2. Can Rails 4 in Action be read and used with Rails 5?
So far my response has been “it likely can, with a few gem version bumps” but I haven’t known the answer for sure. Time to find out, chapter by chapter, line of code by line of code! Let’s dig in.
Note: I’m using the PDF version of the book, so if you’re looking at a physical copy the page numbers may be slightly different.
Chapter 1 - Ruby on Rails, the framework
Rails 4 in Action was written to cover Rails 4.2 (page 2), but now we’re upping the ante to Rails 5.1 (The final version of Rails 5.1 isn’t out just yet, but by the time you’re reading this it probably will be). We recommended at least Ruby 2.1 (page 6), but Rails 5 requires at least Ruby 2.2.2 according to the Rails gemspec. Ruby 2.4.1 is the latest version of Ruby currently out, so you may as well use that!
So let’s check our library versions before we start looking at code (page 6):
$ ruby -v ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-darwin16] $ gem -v 2.6.11 $ rails -v Rails 5.1.0
If you’ve got versions that look similar to those, you should be good to go.
Generating an application
You’ll get a little better error message if you try to name your Rails app as a reserved word (page 7):
# Rails 4 $ rails new test Invalid application name test. Please give a name which does not match one of the reserved rails words. # Rails 5 $ rails new test Invalid application name test. Please give a name which does not match one of the reserved rails words: application, destroy, plugin, runner, test
It would be nice if the error message said “Rails” instead of “rails”, but we can’t always get what we want.
Starting the application
When you start
rails server (page 7) now with Rails 5, by default it will use the Puma webserver, not WEBrick. This is because Rails now needs a multithreaded server to deal with things like ActionCable goodness (which I won’t be touching on in these posts, sadly), but as always it’s configurable in your
The welcome page has had a total facelift, too:
It doesn’t have the helpful guide links anymore - just a link to the Rails homepage in the logo. But that’s alright. You’re reading a pretty awesome book that will help you out.
The generated migration for your
things_i_bought app (page 9) will look slightly different. It now has a migration version number in the class definition:
class CreatePurchases < ActiveRecord::Migration[5.1] def change create_table :purchases do |t| t.string :name t.decimal :cost t.timestamps end end end
And the timestamps line is missing the
null: false argument. In practice, these changes mean your migrations will be more robust - future changes to Rails may mean that migrations created with an earlier version don’t work anymore. Versioning migrations introduces a compatibility layer, ensuring that this will never be a problem moving forward.
Running the migration (page 10) is slightly different now - the existing code will work, but it was thought to be confusing that some Rails-related commands are run via the
rails command and some via
rake. Now all can be run via
bundle exec isn’t needed if you use the binstub that Rails will install for you in the
bin folder of your application, so you can simply run:
$ bin/rails db:migrate
Similarly, if you ever wanted to rollback a migration, you use
bin/rails db:rollback. For the rest of the book, wherever you see
bundle exec rake, you can typically replace it with
Viewing and creating purchases
You can also use
bin/rails server to run your server (page 11), instead of
rails server. It’s good to get into the habit of using the binstubs, even though the command is slightly longer.
The scaffolded code generated by Rails is mostly the same, with only minor changes. These include:
The heading for the listing in figure 1.2 (page 11) is now “Purchases” instead of “Listing Purchases”.
The new view in
app/views/purchases/new.html.erb(listing 1.2, page 11) now passes the defined instance variable
@purchaseto the form partial. Now instead of using
@purchasein the partial, the local variable
purchaseis used. This makes the partial more reusable, for reasons covered on page 91.
app/views/purchases/_form.html.erbpartial (listing 1.3, page 12) has been updated to the new Rails 5.1
form_with(model: purchase, local: true) do |f|. I’ll explain the changes more when we start building our own forms, but for now just know that
form_withis the new way of building forms.
Purchasemodel (listing 1.7, page 14) by default now inherits from
ActiveRecord::Base. When replacing the contents of the file, the first line should now be
class Purchase < ApplicationRecord.
formtag in the HTML source of
app/views/purchases/new.html.erb(listing 1.12, page 18) no longer has
The edit view in
app/views/purchases/edit.html.erb(listing 1.13, page 19) also passes the instance variable
@purchaseto the form partial, the same as the new view.
formtag in the HTML source of
app/views/purchases/edit.html.erb(listing 1.15, page 20) also no longer has
classattributes added, just like the new view.
All-in-all, the changes are mostly superficial - everything else in a scaffold looks and works exactly the same in Rails 5 as it did in Rails 4.
And that’s it for chapter 1! Not a lot has changed so far - Rails 5 is very much an incremental upgrade from Rails 4. It did introduce some big new features, but most of the existing stuff has iterated enough so that it’s rock solid. When we get into building Ticketee there might be some bigger changes, but I’ll cover those when we get to those chapters!
If you’d like to follow along with any of the code being built during this Rails 5 update process, you can check out the GitHub repository: https://github.com/sevenseacat/r4ia-examples-rails-5