I'm having the exact same issue as described on this thread:
Rails 5 only_deleted with cancancan #356
I can access a deleted record, like this:
@area = Area.only_deleted.find(params[:id])
but if I add load_and_authorize_resource to my controller, it'll attempt to run the query like this:
@area = Area.find(params[:id])
which will result in error since it won't find a record with that id on a collection where deleted_at isn't null (not deleted records, the purpose of the Paranoia gem).
If I disable load_and_authorize_resource for the controller or for that very action, it solves the error but it's not a solution since that means losing authorization control.
Is there a fix for this, or is there an authorization gem which plays nice with Paranoia on Rails 5 which I could switch over to?
Thank you.
So, according to documentation on load_and_authorize_resource, the method will attempt to load an instance variable in case one hasn't been set yet, and won't do so if there's a set instance variable, which is precisely why the application was breaking:
load_and_authorize_resourceruns first on the list, and since there were no instance variables set before its call, it does@area = Area.find(params[:id])on its own account, which obviously leads to error, since Paranoia overwrittes finder methods to include a condition to check whether thedeleted_atisNULL.For example, when using the regular (without Paranoia)
Area.find(17), you get a query like this on your console:When using Paranoia, you'd get this query:
This way, records that have been deleted won't be found on common queries since they'll have the
deleted_attimestamp set (deleted_atis nowNOT NULL).To access deleted records, you must use either
with_deletedoronly_deleted, like@area = Area.only_deleted.find(params[:id])or else it won't find the deleted record, hence why I was getting the error
The method
load_and_authorize_resourceloaded@area = Area.find(params[:id])and skippedset_area, so you could delete the method and it would still set the area even if the code is not there.The solution is to simply move the
load_and_authorize_resourcemethod below the callbacks list:UPDATE
You can leave the method call
load_and_authorize_resourceat the top at the stack, but change it toauthorize_resourceso it doesn't attempt to call@area = Area.find(params[:id]), according to this thread.