Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save mctaylorpants/1e20eb4a3756906f75413103fa839dc1 to your computer and use it in GitHub Desktop.
Save mctaylorpants/1e20eb4a3756906f75413103fa839dc1 to your computer and use it in GitHub Desktop.
Better callback deprecation warnings for Rails 5.0
# A monkey-patch to make detecting deprecated
# callbacks easier, because a stack trace is
# not the greatest when it comes to callbacks.
#
#
# Original code:
# https://github.com/rails/rails/blob/c4d3e202e10ae627b3b9c34498afb45450652421/activesupport/lib/active_support/callbacks.rb#L766-L788
require "active_support/callbacks"
module ActiveSupport
module Callbacks
module ClassMethods
def deprecated_false_terminator # :nodoc:
Proc.new do |target, result_lambda|
terminate = true
catch(:abort) do
result = result_lambda.call if result_lambda.is_a?(Proc)
if Callbacks.halt_and_display_warning_on_return_false && result == false
# the scope that `result_lambda` is created in contains the filter
# that we need to identify the callback with, so let's pull it
# out of the binding.
filter = result_lambda.binding.local_variable_get(:filter) rescue nil
display_deprecation_warning_for_false_terminator(target, filter)
else
terminate = false
end
end
terminate
end
end
def display_deprecation_warning_for_false_terminator(target=nil, filter=nil)
ActiveSupport::Deprecation.warn(<<~MSG)
Returned `false` from callback in `#{target.class.name}##{filter}`!
Returning `false` in Active Record and Active Model callbacks will not implicitly halt a callback chain in Rails 5.1.
To explicitly halt the callback chain, please use `throw :abort` instead.
MSG
end
end
end
end
@mctaylorpants
Copy link
Author

Use the patch like this:

# config/application.rb

# IMPORTANT: the patch needs to be added before booting Rails,
# since it needs to take effect before ActiveRecord loads.
require_relative "../extensions/rails_patches/rails_5_1_callback_halting_monitor"

require_relative "boot"
require "rails/all"

# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)

module MyApp
  class Application < Rails::Application
    ...
  end
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment