Cancel Recurly Subscription Programmatically

Different ways to cancel a recurly subscription using the ruby sdk.

When you need to cancel a Recurly subscription in Ruby, the Recurly gem provides a few options depending on whether you want an immediate cancellation or one at the end of the billing period.

Bulk Insert Records That Don’t Already Exist

A common pattern is inserting records in bulk, skipping any that already exist in the database. This avoids N+1 queries and is far more efficient than checking each record individually.

Using fast_inserter

The fast_inserter gem provides a clean way to batch-insert records efficiently:

# Get the IDs of the students
student_ids = Student.where(id: *params[:student_emplids]).pluck(:id)

# Get students that already have group assignments
student_with_group_ids = StudentGroup.where(student_id: *params[:student_emplids]).pluck(:student_id)

# Bulk insert only the ones that don't exist yet
StudentGroup.bulk_insert((student_ids - student_with_group_ids).map { |id|
  { student_id: id, group_id: @group.id }
})

Using upsert with ActiveRecord

If you’re on Rails 6+, you can use upsert_all to insert records that don’t already exist:

# Prepare the records
students = Student.where(id: params[:student_emplids])
existing_ids = StudentGroup.where(student_id: params[:student_emplids]).pluck(:student_id)

records = students.where.not(id: existing_ids).map do |student|
  { student_id: student.id, group_id: @group.id, created_at: Time.current, updated_at: Time.current }
end

StudentGroup.upsert_all(records, unique_by: [:student_id, :group_id])

Using Raw SQL with INSERT … ON CONFLICT

For PostgreSQL, you can use ON CONFLICT DO NOTHING to skip duplicates:

StudentGroup.connection.execute(<<~SQL)
  INSERT INTO student_groups (student_id, group_id, created_at, updated_at)
  SELECT id, #{@group.id}, NOW(), NOW()
  FROM students
  WHERE students.id IN (#{params[:student_emplids].join(',')})
  ON CONFLICT (student_id, group_id) DO NOTHING
SQL

External Resources