BigBinary Blog

We write about Ruby on Rails, React.js, React Native, remote work, open source, engineering and design.

Rails 6.1 allows associations to be destroyed asynchronously

This blog is part of our Rails 6.1 series.

In Rails 6.1, Rails will enqueue a background job to destroy associated records if dependent: :destroy_async is setup.

Let's consider the following example.

class Team < ApplicationRecord
  has_many :players, dependent: :destroy_async
end

class Player < ApplicationRecord
  belongs_to :team
end

Now, if we call destroy method on an instance of class Team Rails would enqueue an asynchronous job to delete the associated players records.

We can verify this asynchronous job with a following test case.

class TeamTest < ActiveSupport::TestCase
  include ActiveJob::TestHelper

  test "destroying a record destroys the associations using a background job" do
    team = Team.create!(name: "Portugal", manager: "Fernando Santos")
    player1 = Player.new(name: "Bernardo Silva")
    player2 = Player.new(name: "Diogo Jota")
    team.players << [player1, player2]
    team.save!

    team.destroy

    assert_enqueued_jobs 1
    assert_difference -> { Player.count }, -2 do
      perform_enqueued_jobs
    end
  end
end

Finished in 0.232213s, 4.3064 runs/s, 8.6128 assertions/s.
1 runs, 2 assertions, 0 failures, 0 errors, 0 skips

Alternatively, this enqueue behavior can also be demonstrated in rails console.

irb(main):011:0> team.destroy
  TRANSACTION (0.1ms)  begin transaction
  Player Load (0.6ms)  SELECT "players".* FROM "players" WHERE "players"."team_id" = ?  [["team_id", 6]]

Enqueued ActiveRecord::DestroyAssociationAsyncJob (Job ID: 4df07c2d-f55b-48c9-8c20-545b086adca2) to Async(active_record_destroy) with arguments: {:owner_model_name=>"Team", :owner_id=>6, :association_class=>"Player", :association_ids=>[1, 2], :association_primary_key_column=>:id, :ensuring_owner_was_method=>nil}

Performed ActiveRecord::DestroyAssociationAsyncJob (Job ID: 4df07c2d-f55b-48c9-8c20-545b086adca2) from Async(active_record_destroy) in 34.5ms

Check out the pull request for more details.

Srijan Kapoor in Rails 6.1
Dec 08, 2020
Share

Subscribe to our newsletter