I have recently upgraded from Rails 4.2 to 5.0. I know about the change in callback halting using throw(:abort) instead of returning false. My problem is that I can't make the deprecation warnings go away.
DEPRECATION WARNING: 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.
I have made config/initializers/callback_terminator.rb file with following code
ActiveSupport.halt_callback_chains_on_return_false = false
but I am not still not able to get rid of the warning. Nor am I getting the expected behaviour. It seems that this configuration is not being applied.
Is there something I am missing?
Put the config in after config.after_initialize block in application.rb file like this.
config.after_initialize do
ActiveSupport.halt_callback_chains_on_return_false = false
end
Related
I'm migrating from Rails 4.1 to Rails 5.1 and got the following deprecation warning:
DEPRECATION WARNING: 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.
I added throw(:abort) in callbacks that rely on returning false to halt the callback chain. When I run tests, I got a lot of errors like the following:
Error:
UserControllerTest#test_: the update action should have updated user record. :
UncaughtThrowError: uncaught throw :abort
app/controllers/application_controller.rb:298:in `throw'
app/controllers/application_controller.rb:298:in `check_access'
I'm a bit confused. Since Rails 5 asks people to use throw :abort in callbacks, why the UncaughtThrowError?
Am currently at Rails 5.1.7.
Any help is appreciated. Thanks.
This issue only exists in test environment. Everything runs fine in development environment.
I am facing a strange issue after recently upgrading to Rails 5.0.0.1 from Rails 4.2.7.1. Everything was working fine before this upgrade.
In one of my models, I use ActiveJob to perform a task.
# webhook_invocation.rb
def schedule_invocation
WebhookRequestJob.perform_later(id)
end
def init
remember_webhook # No DB changes
init_errors_context # No DB changes
flow_step_invocation.implementation = self
flow_step_invocation.save!
return unless calculate_expressions # No DB changes
calculated! # An AASM event, with no callbacks
schedule_invocation
end
and in WebhookRequestJob#perform, I retrieve the object using the ID supplied
# webhook_request_job.rb
def perform(webhook_invocation_id)
invocation = WebhookInvocation.find_by(id: webhook_invocation_id)
invocation.run_request
end
The problem is that in the #perform, it cannot find the record (invocation becomes nil). I even tried putting p WebhookInvocation.all as the first line, but all it prints is an empty collection. On the other hand, if I try p WebhookInvocation.all in #schedule_invocation method, it properly prints out all the objects of WebhookInvocation.
There is no exception being raised, no lines of warnings either.
Edit 1:
I even tried passing the object directly to #perform_later i.e. WebhookRequestJob.perform_later(self), but the received object at #perform is nil.
Edit 2:
I noticed that there are some messages like Creating scope :fail. Overwriting existing method FlowStepInvocation.fail, caused by using AASM. I eliminated them by using create_scopes: false. But that still didn't solve the problem.
My guess from the info you supplied is that you have are calling the schedule_invocation method in a after_save or after_create callback. Since the callback is called, ActiveJob might start processing the job even before the object is actually persisted (before COMMIT is done). In this case your record will not show up in the database when job is processed and you will get an empty collection or nil.
To fix this change your callback to after_commit to make sure that the COMMIT action has happened before you queue the job.
It turns out that config.active_job.queue_adapter was set to :inline as default before Rails 5, but it is set to :async in Rails 5.
This made the specs to fail (don't know why). To resolve this, I put the following line in my config/environments/test.rb:
config.active_job.queue_adapter = :inline
I get this message when I run my feature specs:
DEPRECATION WARNING: ActiveRecord::Base.raise_in_transactional_callbacks= is deprecated, has no effect and will be removed without replacement.
I am using Rails 5.0.0.rc1 and am not sure what is throwing this deprecation warning.
I had this in my application.rb file. I removed it and the deprecation warning went away:
config.active_record.raise_in_transactional_callbacks = true
I'd like tips on what this deprecation warning actually means and to know what triggers this deprecation warning.
I believe this behaviour was added between 4.1 and 4.2 as a temporary solution to a problem which is no longer relevant in rails 5:
http://edgeguides.rubyonrails.org/upgrading_ruby_on_rails.html#error-handling-in-transaction-callbacks
Currently, Active Record suppresses errors raised within
after_rollback or after_commit callbacks and only prints them to the
logs. In the next version, these errors will no longer be suppressed.
Instead, the errors will propagate normally just like in other Active
Record callbacks.
When you define an after_rollback or after_commit callback, you will
receive a deprecation warning about this upcoming change. When you are
ready, you can opt into the new behavior and remove the deprecation
warning by adding following configuration to your
config/application.rb:
config.active_record.raise_in_transactional_callbacks = true
For clarification, as #pixelearth suggests my comment below isn't clear/prominent enough. In Rails 5 and later remove the line from config/application.rb:
config.active_record.raise_in_transactional_callbacks = true
Writing this here for more visbility for #R. Hatherall's comment.
I was getting this warning when upgrading to 5 not becuase I DIDN't have the following setting in application.rb, but because I DID.
In rails 5 remove the following line from application.rb
config.active_record.raise_in_transactional_callbacks = true
My Rails 4/Ruby 2 app is throwing the following warning every time my RSpec tests create a FactoryGirl object: "DEPRECATION WARNING: This dynamic method is deprecated. Please use e.g. Post.find_or_create_by(name: 'foo') instead."
This warning is not thrown when I run my app in development. Is FactoryGirl's code throwing this? I tried to find some information but it doesn't look like other people are getting this.
If you tell Rails to give you a full stack trace for the deprecation warning, you should be able to diagnose it pretty easily. The warnings are coming from a library called ActiveSupport::Deprecation - tell it to run in debug mode.
# config/environments/test.rb
ActiveSupport::Deprecation.debug = true
For me, the warnings were caused by an old version of the Stringex library.
FactoryGirl would make a new model, which would trigger a call to one of the Stringex methods, which would raise the warning, although there was no way to see that until I turned on full stack traces. bundle update stringex solved the issue with no problem.
It looks like it's coming from ActiveRecord.
module DeprecationWarning
def body
"#{deprecation_warning}\n#{super}"
end
def deprecation_warning
%{ActiveSupport::Deprecation.warn("This dynamic method is deprecated. Please use e.g. #{deprecation_alternative} instead.")}
end
end
I'm not sure why you're not getting the warnings in development. Is your environment suppressing the warnings?
In Rails 3.2 I get deprecation warning, when using logger.silence {}. In release note:
"ActiveSupport::BufferedLogger#silence is deprecated. If you want to squelch logs for a certain block, change the log level for that block."
How I can easily change log level for the block?
It appears that logger.silence is being replaced by simply silence:
logger.silence do
#your silenced code here
end
becomes:
silence do
#your silenced code here
end
At least it doesn't generate the depreciation warning anymore, and it does silence the logged output.
The first answer is good, but not complete. We were having issues trying to figure this one out too. silence &block has been deprecated in Rails 3, so you should use the updated syntax calling the logger directly:
Rails.logger.silence do
# your code here...
end
For even more sweet, sweet customizability, you can pass a log level to #silence().
def silent_method
old_level = Rails.logger.level
Rails.logger.level = 7
result = your_code_here
Rails.logger.level = old_level
result
end
Or quietly{}, since silence requires a stream.