Suppress save events in Rails 5

Abhishek Jain

By Abhishek Jain

on March 11, 2016

This blog is part of our  Rails 5 series.

Rails 5 added suppress method which is used to prevent the receiver from being saved during the given block.

Use case for suppress method

Let's say, we have an E-commerce application, which has many products. Whenever new product is launched then subscribed customers are notified about it.

1
2class Product < ApplicationRecord
3  has_many :notifications
4  belongs_to :seller
5
6  after_save :send_notification
7
8  def launch!
9    update_attributes!(launched: true)
10  end
11
12  private
13
14  def send_notification
15    notifications.create(message: 'New product Launched', seller: seller)
16  end
17end
18
19class Notification < ApplicationRecord
20  belongs_to :product
21  belongs_to :seller
22
23  after_create :send_notifications
24
25  private
26
27  def send_notifications
28    # Sends notification about product to customers.
29  end
30end
31
32class Seller < ApplicationRecord
33  has_many :products
34end
35

This creates a notification record every time we launch a product.

1
2>> Notification.count
3=> 0
4
5>> seller = Seller.last
6=> <Seller id: 6, name: "John">
7
8>> product = seller.products.create(name: 'baseball hat')
9=> <Product id: 4, name: "baseball hat", seller_id: 6>
10
11>> product.launch!
12
13>> Notification.count
14=> 1
15

Now, we have a situation where we need to launch a product but we don't want to send notifications about it.

Before Rails 5, this was possible only by adding more conditions.

ActiveRecord::Base.Suppress in Rails 5

In Rails 5, we can use ActiveRecord::Base.suppress method to suppress creating of notifications as shown below.

1
2class Product < ApplicationRecord
3  def launch_without_notifications
4    Notification.suppress do
5      launch!
6    end
7  end
8end
9
10>> Notification.count
11=> 0
12
13>> product = Product.create!(name: 'tennis hat')
14=> <Event id: 1, name: "tennis hat">
15
16>> product.launch_without_notifications
17
18>> Notification.count
19=> 0
20

As we can see, no new notifications were created when product is launched inside Notification.suppress block.

Checkout the pull request to gain better understanding of how suppress works.