All PostsInside Skylight Learn about Skylight

Rails 5... is ALIVE!!!

While Skylight itself supports Rails 5 automatically, we had not yet upgraded the Rails portion of the app on our end until last week. I optimistically volunteered to make the upgrade, thinking it would not take more than a day, maybe two, tops.

Not so much.

For context, although I've been working with Rails for about two years, I have never upgraded a Rails app--only Ember apps. Before I was aware of the rails app:update command, I tried just updating our version of Rails in the Skylight Gemfile and bundling, which then led me through a series of errors each time I bundle'd and updated the version of another dependency.

Not long after that, Godfrey told me about rails app:update and we decided to pair on it so we could go through all the various files that would be updated. After a bit of a Git fail that erased much of my previous work, we were able to get the app back to a pretty good place! If I had known about rails app:update from the start I think it would have helped a lot - next time I will use it right away for sure!

Even with that, I still had to go through our app as well as a little Rails engine we use for billing and repeatedly upgrade various dependencies by hand, bundle, get an error, upgrade another one, etc. Not the worst thing ever but definitely not fun.

Once everything was seemingly upgraded, we still had to deal with the various and sundry errors that began popping up. One of the first was our use of only in the context of controllers, like so:

module BlingBling
  class CustomersController < BlingBling::ApplicationController

    rescue_from ::Stripe::CardError, with: :invalid_card, only: [:update, :update_card]

    def show
      # stuff
    end

    def update
      # other stuff
    end

    def update_card
      # yet moar stuff
    end
    
    private
    
    def invalid_card
      render_errors card: "is invalid"
    end
  end
end

I kept seeing an error telling me that I couldn't use only there. I couldn't find any documentation or blog posts on the topic but all errors pointed at only being for filters and nothing else (i.e. before, after, around). After much tweaking and experimentation I went with:

module BlingBling
  class CustomersController < BlingBling::ApplicationController

    def show
      # stuff
    end

    def update
      handle_invalid_card {
        # other stuff
      }
    end

    def update_card
      handle_invalid_card {
        # yet more stuff
      }
    end
    
    private
    
    def handle_invalid_card
      begin
        yield
      rescue ::Stripe::CardError => error
        render_errors card: "is invalid"
      end
    end
  end
end

Update 8/1/2016: After we posted this blog, an intrepid Skylight user/blog-reader posted about this error and brought more information to our attention. It turns out that the original code was broken, the only keyword never should have worked with rescue_from, but it failed silently until we upgraded to Rails 5, which started throwing an error where previous Rails versions had not. So previously, rescue_from was being called on every controller action (ignoring the only), and I unintentionally fixed a bug by explicitly calling it on the correct controller actions.

Another error I encountered was calling fetch on an ActiveRecord::Relation (which users.with_inactive is)... now it needs to be transformed into an array beforehand. For some reason, users.with_inactive used to respond to fetch and no longer does.

Previous code:

  def owner
    users.with_inactive.fetch(0)
  end

Now looks like:

  def owner
    # `user.with_inactive` is an ActiveRecord::Relation so needs
    # to be an Array to use `fetch`
    users.with_inactive.to_a.fetch(0)
  end

Again, couldn't find much on why this changed, but it apparently did, because all of a sudden we were getting an error that we weren't getting before the upgrade. Maybe it was somehow due to a dependency upgrade and not Rails 5, but it's hard to say since it all happened at the same time.

We also discovered that strong params appear to no longer be optional, but required! I couldn't find any documentation on this, but we found that our contact page (one of the few spots where we had not yet moved over to strong params) was suddenly throwing a big error when we tried to send an email using the form.

So we had to move it over from this:

def create
  @contact = Contact.new(params[:contact])
end

to this:

def create
  @contact = Contact.new(contact_params)
end

private

def contact_params
  params.require(:contact).permit(:name, :email, :message)
end

Problem solved!

Our final, and most annoying issue, was related to updating the Intercom gem from 2.4.3 to 3.5.2. This occurred at some point during the initial upgrade process so it took some time for us to recognize that the upgrade was the origin of the issue. We kept seeing crazy errors around our Intercom service that were difficult to understand, until we realized that their API had changed significantly after 3.0 and one of the methods we were using in a pretty integral part of our Intercom service had been removed.

There were enough breaking changes that we ended up going back to the old version that we had before the upgrade (2.4.3). In retrospect, we should have locked down the version of the Intercom gem in our Gemfile, but now we know!

We'll have to deal with this eventually, but it took me long enough to play whack-a-mole with all the sudden errors after the Rails 5 upgrade that it didn't seem like a good use of my time to try and rewrite our Intercom service.

Once the Intercom issue was figured out, the app began running smoothly and we all moved on with our lives! Except for the issue of those pesky deprecation warnings. They're everywhere! Every time we run our test suite or Rails servers we are absolutely flooded with deprecation warnings. We've started tackling them in earnest so that we'll be able to upgrade easily to 5.1, but it's not been totally smooth sailing for us.

But, that's a story for another time! Hopefully your Rails 5 upgrades have been smoother than ours. If I come across any useful tips or tricks during the process of dealing with the deprecation warnings, I'll be sure and share them here!

Skylight

Start your free month or refer a friend and get a $50 credit.