Safer sandboxing in Rails
Oinak

Oinak @oinak

About: dad, vimmer, #ruby lover, #elixirlang & #crystallanguage curious , learning ally, gnu/🐧 user, 🚲 rider, scifi lover (he/him)

Location:
Spain
Joined:
Aug 5, 2019

Safer sandboxing in Rails

Publish Date: Aug 6
0 0

Ruby on Rails console has a very interesting feature, that you can see on its documentation:

As you can see it says Any modifications you make will be rolled back on exit.

But that vague language can lead to some unexpected surprises.

This "sandbox mode" is based on a db transaction that is automatically rolled back when wou exit the console, effectively undoing any changes you may have made ... on the db.

Unfortunately, modern applications can have a wide range of side effects, besides db-based data persistence.

These is a non exhaustive list of things you might need to be on the lookout for:

  • POST/PUT external calls
  • Emails sent
  • Payments
  • Non db-based file uploads (or deletions)

One thing you can do, is prepare your classes to be called safely

class PotatoReport
  def initialize(data, dry_run: true)
    @data = data
    @dry_run = dry_run
  end

  def run
    @report = generate_report
    write_file
  end

private

  attr_reader :dry_run

  def write_file
    Rails.logger.info "[PotatoReport] generating #{filename} on #{timestamp}"
    return if dry_run # or write the file to stdout instead

    File.write(report_filename, report_content)
  end

  #...

end
Enter fullscreen mode Exit fullscreen mode

Then on your application code you can call:

PotatoReport.new(data, dry_run: false).run
Enter fullscreen mode Exit fullscreen mode

but on the console, no matter if you pass dry_run: true or forget about it, you are not going to be writing a file.

The thing is that if you do this, you need to be on the look for when some of your objects are calling others to make sure you pass your dry_run flag along.

I hope this save you some headaches. It has certanly allowed me to do some production data changes with a greater peace of mind.

Cover pic: Gil Garcia

Comments 0 total

    Add comment