Rails 5 Paranoia - How can I 'show' a deleted record?

10.1k Views Asked by At

Upon soft-deleting a record, I'm unable to call it on the show action on the controller, for it looks for a record matching the record's ID WHERE deleted_at IS NULLL, which is correct given the purpose of the gem, but I'd still like to be able to access it on a sort of a "readonly" state, within the application, in order to allow the user to review the archive and possibly restore it.

How can I work around the deletion scope so that I can access the object again?

UPDATE 1

By @slowjack2k's advice, I can access the soft-deleted records with the following query:

 @area = Area.only_deleted.find(params[:id])

A new problem arose afterwards, due to CanCanCan's load_and_authorize_resource: it attempts to call

 @area = Area.find(params[:id])

ignoring the only_deleted filter, resulting in error since the selected id is only found where deleted_at is not null (not deleted), and disabling the authorization "fixes" it, so it must be an issue between CanCanCan and Paranoia.

Here's a thread with the exact same issue: https://github.com/rubysherpas/paranoia/issues/356

Here's the new issue thread on StackOverflow: Rails 5 compatibility between Paranoia and CanCanCan, compromised?

I'll update it again with the solution if I find one, thank you.

UPDATE 2

The issue was solved and the solution can be found on the new issue thread I've mentioned above.

2

There are 2 best solutions below

0
slowjack2k On BEST ANSWER

You can use YourModel.readonly.find_with_deleted(params[:id]) or YourModel.readonly.with_deleted.find(params[:id])

2
Moataz Zaitoun On

I've been throw this before and I'll explain my approach to solve this..

Overview: Giving that I have a Model Called Items, I'll have a page that will display all Soft Deleted Items I'll call the inactive. Using the same template of index action

First you should create a route

  resources :items

    collection do
      get 'inactive'
    end

  end

Second you should create a controller action...

  def inactive
    @Items = Items.only_deleted
    render action: :index
  end

Third, I'll go to ../items/inactive And it'll display the in active or archived Items

You may also after that use...

<%= link_to "Archived Items", inactive_items_path %>

In your views to go to that page

Update

Here I should mention that using the index view to render the inactive Items collection may leave you with broken links.

views/items/index.html.erb

<td><%= link_to 'Show', merchant %></td>
<td><%= link_to 'Edit', edit_merchant_path(merchant) %></td>
<td><%= link_to 'Destroy', merchant, method: :delete, data: { confirm: 'Are you sure?' } %></td>

So that leave you with a choice to make, Whether you choose to group the edit links for the normal Items and put it in a partial then group the inactive links and put it in another partial, Then to render the partial depending on which action is rendering the view.

Or Option #2 is to lose the render action: :index line and make a separate view inactive.html.erb with its links and save your self the headache. Although it would be against the DRY principal.