Skip to content
PLAY VIDEO PLAY VIDEO PLAY VIDEO
By Raluca Pintilii

Handling deletes with Null Object Pattern in Ruby

I recently worked on a project for an Australian company who wanted to ensure they were GDPR compliant in how they handled personal data through their website and requests to delete user accounts.

If we want the user and all the associated data (blog posts, comments, etc) deleted, it is easy, we just need to add dependent: :destroy to the relations and Rails takes care of that for us.

But in this scenario, the client wanted to keep the user-related data after a user account was deleted.

General Data Protection Regulation (GDPR) background:

By way of background, since the GDPR was approved for the European Union in May 2018, it is more and more common for users to ask for their accounts to be deleted. The EU General Data Protection Regulation (GDPR) generally applies to the data processing activities of data processors or controllers where:

  • an establishment of the controller or processor is in the EU
  • the controller or processor is outside the EU, and the processing activities are related to:

    ○ offering goods or services to individuals in the EU (irrespective of whether a payment is required)
    ○ monitoring the behaviour of individuals in the EU, where that behaviour takes place in the EU (see Article 3).

So a US or Australian business of any size may need to comply if they have an establishment in the EU, if they offer goods and services in the EU, or if they monitor the behaviour of individuals in the EU. And in this day and age this encompasses a lot of companies.

Australian privacy law doesn’t include the “right to be forgotten” which is covered in the GDPR. So I had to ensure this was addressed in our client’s code.

Deleting accounts:

Let’s say you have an awesome blog made in Ruby on Rails, where people can create accounts and add posts. What happens if someone who had posted articles on your blog, now asks for their account to be deleted?

There are several ways to deal with this, but in this article, I’d like to cover the null object way.

For this, let’s imagine we have a normal Ruby on Rails blog, with posts and users, and we need to set it up so users can be deleted. Let's see what the code could look like, and what changes we need to add in order to be able to delete users and have the application still working properly.

On the model User, generically, we have something like this:

# app/models/user.rb

Class User < ApplicationRecord
  has_many :posts

  def full_name
    "#{first_name} #{last_name}"
  end
end

And the Post model should look like this:

# app/models/post.rb

Class Post < ApplicationRecord
  belongs_to :user

  def user_name
    user.full_name
  end
end

The issue to address is when users ask to delete their accounts, their posts become orphans, and unless we want to delete them, we have to deal with this situation.

If, on the page where we display the posts, we also display the author name, picture, or any other user attribute, then after we delete an account, these pages will be broken, since calling all these methods on nil will cause a method missing error.

So, how do we fix this using the Null Object Pattern?

We should start by adding a nulls folder under the app directory. From there add the following file:

# app/nulls/null_user.rb

Class NullUser

end

Then, on the Post model, change the relation to read the following:

belongs_to :user, optional: true

This will allow us to safely delete users with posts without getting any constraint errors.

If you have any custom validation on the user_id presence, please remove them as well.

Ok, so now that we can remove users with posts, we need to make sure the post pages (index, show) won’t break when we visit them due to calling methods on nil.

Let’s continue our example using the user_name method.

On the Post model file, add the following changes:

# app/models/post.rb

Class Post < ApplicationRecord
  belongs_to :user, optional: true

  def user_name
    user&.full_name || NullUser.new.user_name
  end
end

Now let’s implement the user_name method on the NullUser class:

# app/nulls/null_user.rb

Class NullUser
  def user_name
    'User deleted'
  end
end

Now when calling user_name on a post without user, it will return 'User deleted’ instead of breaking. Feel free to customize the message you want to return.

But what if we have multiple methods on the Post model for retrieving its author details (eg. age, avatar, posts count, and so on)? To keep the code DRY, we can edit the NullUser class like this:

# app/nulls/null_user.rb

Class NullUser
  def method_missing(*args, &block)
    'User deleted'
  end
end

Then edit the Post model to the following:

# app/models/post.rb

Class Post < ApplicationRecord
  belongs_to :user, optional: true


  def user
    super || NullUser.new
  end
end

And that’s how you can use the null object pattern in Ruby on Rails to DRY your code and preventing method missing errors.

Latest Articles by Our Team

Our expert team of designers and developers love what the do and enjoy sharing their knowledge with the world.

We Hire Only the Best

reinteractive is Australia’s largest dedicated Ruby on Rails development company. We don’t cut corners and we know what we are doing.

We are an organisation made up of amazing individuals and we take pride in our team. We are 100% remote work enabling us to choose the best talent no matter which part of the country they live in. reinteractive is dedicated to making it a great place for any developer to work.

Free Community Workshops

We created the Ruby on Rails InstallFest and Ruby on Rails Development Hub to help introduce new people to software development and to help existing developers hone their skills. These workshops provide invaluable mentorship to train developers, addressing key skills shortages in the industry. Software development is a great career choice for all ages and these events help you get started and skilled up.

  • Webinars

    Webinars

    Webinars are our online portal for tips, tricks and lessons learned in everything we do. Make the most of this free resource to help you become a better developer.

    Learn more about webinars

  • Installfest

    Installfest

    The Ruby on Rails Installfest includes a full setup of your development environment and step-by-step instructions on how to build your first app hosted on Heroku. Over 1,800 attendees to date and counting.

    Learn more about Installfest

  • Development Hub

    Development Hub

    The Ruby on Rails Development Hub is a monthly event where you will get the chance to spend time with our team and others in the community to improve and hone your Ruby on Rails skills.

    Learn more about Development Hub

Next Community Events

Find more events

Get the “reinteractive Review” Monthly Email