In some instances, we want to 'softly' destroy records; persisting in the database but making it inaccessible
through ActiveRecord queries where defined. Trashing is what many would call and while there is the option of using gems
such as acts_as_trashable
, it is always a good idea to minimize the number of external dependencies.
One approach to this would be to add trashed_at
attribute to the ActiveRecord::Base
class then querying for records whose column trashed_at
value is nil
This is what we are going to do only that we are creating a concern with the required functionality to be used across mutilple
Here's the link to code
I will name my app trashing
so let's go ahead and create a new app. I'm using the lastest stable version
of rails 5 i.e version
18.104.22.168. We'll take advantage of the rails-api gem, which, starting with Rails 5, now comes built in since we only need
as JSON response as an output for our ActiveRecord queries.
$ rails _22.214.171.124_ new trashing --api
$ cd trashing
make sure you've got all the dependencies installed by running
$ bundle install
Let's go ahead a scaffold two new models. In this case I will name mine Post and Comment with each having two new columns body and
$ rails g scaffold post body:text trashed_at:datetime
$ rails g scaffold comment body:text trashed_at:datetime
migrate the db changes
$ rails db:migrate
firing the localhost and accessing /comments and /posts pages should return nil arrays
Note the query in logs
We are going to create our trashable concern. A concern is basically a way of organizing code in this case by having a common functionality
across multiple models in one file. A DRY of sorts. Inside model/concerns create a file named trashable.rb with the following
We're extending ActiveSupport::Concern to get hold of included function which typically includes the two scopes in the models
where the trashable module will be included
The default scope is set to only returns record that have trashed_at column as nil meaning trashed items won't be
included. On the other hand, trashed scope does the opposite e.g Comment.trashed.
trashed? method returns Boolean checking whether a record has trashed_at as not nil.
Let's include the trashable concern in our two models
Using Faker gem I created 10 records for each ActiveRecord::Base class.
Firing the localhost
Let's go ahead trash the first 5 records of each model i.e:
The resultant response should only return untrashed items:
That's it! You can go ahead and add other functionalities to the concern e.g unmuting trashed items.