1

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.

Community
  • 1
  • 1

2 Answers2

6

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

slowjack2k
  • 2,566
  • 1
  • 15
  • 23
1

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.

Moataz Zaitoun
  • 729
  • 1
  • 7
  • 18
  • Hi @moataz-zaitoun, thank you for your suggestion! I have a filter to display only the records that are deleted on the same place as the index, so if the filter is on, the collection passed to index action on the controller will be the filtered by only_deleted, else, gets all records which weren't deleted. I also use the filter for the record display, so if the filter is on, it'll find the record among the collection of deleted records, else, it'll find among the active records. This way you don't need a second template for different collections! – Filipe Gorges Reuwsaat Oct 05 '16 at 18:24
  • My issue was a mix between @slowjack2k's answer and a new problem arose with CanCanCan load_and_authorize_resource, ignoring the with_deleted filter and attempting to find the record among the normal collection – Filipe Gorges Reuwsaat Oct 05 '16 at 18:25