DEV Community

hatsu
hatsu

Posted on

Introducing the `script` Folder in Rails 8 and a New Gem for Browser-Based Data Migration

I usually write in Japanese, so please pardon any awkward phrasing in my English.

Introduction

None of us want to log into a production environment via SSH and manually fiddle with data using rails c, right? Surely no one is doing that… or at least, let’s hope not.

That said, in some workplaces that aren’t fully set up yet, it might still happen occasionally. I’ve found myself doing it now and then, and I started wondering if there was a better way.

With that in mind, I experimented with a potential solution by creating a new Gem. (Full disclosure: I’m quite new to making Gems.)

This Gem also ties into the script folder, a feature introduced in Rails 8.

In this article, I’ll cover:

  • The challenges of data migration
  • An introduction to the relatively unknown script folder in Rails 8
  • The new Gem I’ve created to tackle these issues

But first, let’s jump right into what I made.

The Gem I Created: Scriptor

scriptor2.gif

What can it do?

  • Browse your script folder’s code right in the browser
  • Execute scripts from the script folder via the browser
  • View execution history of those scripts through the browser

Check out the repository here:

https://github.com/hatsu38/scriptor

Before I dive into the background of why I made it, let’s talk about how data migration is often handled.

How Do You Handle Data Migration?

Data migration strategies often come up in discussions. Common approaches include using maintenance_tasks gem, data_migrate gem, or simply running rake tasks.

I personally rely on the maintenance_tasks gem at work. The Rails Guide even recommends using maintenance_tasks instead of manipulating data directly in migrations.

However, if your needs aren’t extensive enough to justify maintenance_tasks, it’s still common to write and run a rake task. Before maintenance_tasks came along, that was often the go-to solution.

Among the variety of options available, a new but relatively unknown feature was introduced with Ruby on Rails 8.0.0: the script folder.

This feature was added via this pull request:

https://github.com/rails/rails/pull/52335

About the script Folder

The Rails Guide describes the script folder as:

A place to store disposable or general-purpose scripts and benchmarks.

The script/USAGE file further clarifies:

Generate a one-off or general purpose script, such as a data migration script, cleanup script, etc.

In other words, the script folder is well-suited for one-off data migrations. Quietly and without much fanfare, Rails 8 introduced a first-party solution for these single-run data migration needs.

How to Use the script Folder

Using the script folder is straightforward. Just run:

bin/rails generate script my_script
Enter fullscreen mode Exit fullscreen mode

This command generates a file at script/my_script.rb with the following default content:

require_relative "../config/environment"

# Your code goes here
Enter fullscreen mode Exit fullscreen mode

You can modify this file to include any Rails code you need.
For example, you might write a quick data migration like this:

require_relative "../../config/environment"

title, body = ARGV

if post = Post.find_by(title: title)
  post.update!(body: body)
  puts "Post updated!"
else
  Post.create!(title: title, body: body)
  puts "Post created!"
end
Enter fullscreen mode Exit fullscreen mode

To run it, simply do:

ruby script/my_script.rb hello world
Enter fullscreen mode Exit fullscreen mode

This approach is handy for simple, one-off scripts. For more background, you might check out this discussion:
Is there any “official” way to organize one-off scripts?

Running These Scripts from the Browser and Managing Execution History

While the script folder is convenient, there’s still a catch: I don’t want to SSH into production to run these scripts. Ideally, I’d like to run them from a browser and keep an execution log for auditing purposes.

That’s exactly why I created Scriptor.

Once again, here’s a quick look:

scriptor2.gif

https://github.com/hatsu38/scriptor

A Quick Overview of Scriptor

Scriptor allows you to:

  • Browse scripts from the script folder via the browser
  • Execute these scripts from the browser
  • View a history of past executions

For example, let’s say your script folder looks like this:

❯ tree script                                       
script
├── migration
│   ├── hoges.rb
│   └── posts.rb
└── my_script.rb

2 directories, 3 files
Enter fullscreen mode Exit fullscreen mode

Navigating to http://localhost:3000/scriptor displays a list of these scripts:

スクリーンショット 2024-12-20 2.05.09.png

Clicking on a script’s detail page shows its code:
FireShot Capture 068 - Scriptor - localhost.png

From this page, you can click the 🛠️Run Script button to execute the script. If the script requires arguments, you can input them into a text field before execution.

スクリーンショット 2024-12-20 2.36.33.png

At the bottom of the page, you can view the execution history:
スクリーンショット 2024-12-20 2.36.38.png

The execution history stores:

  • Status (running, success, error)
  • Start time
  • End time
  • Executed command
  • Targeted file

And more.

Installation

It’s easy to get started:

  1. Add the gem:

    bundle add scriptor
    
  2. Run the installer:

    bin/rails generate scriptor:install
    

    This will:

    • Add mount Scriptor::Engine => "/scriptor" to config/routes.rb
    • Create a migration file ****_create_scriptor_executions.scriptor.rb
  3. Place your scripts in the script folder, and they’ll appear at http://localhost:3000/scriptor.

That’s it! You’ve got a handy way to run and manage scripts directly from the browser.

Conclusion

Rails 8 introduced the script folder as a first-party solution for running one-off scripts, including simple data migrations. Wanting to leverage this feature more conveniently, I ended up building a Rails Engine Gem—Scriptor—to execute these scripts from the browser and log their histories.

I’m new to Gem development, but I had a lot of fun making it, and I think it turned out pretty well. Of course, it’s still missing some features like English documentation and comprehensive tests, so contributions are welcome. Stars on GitHub are also much appreciated!

Check out the repo:
https://github.com/hatsu38/scriptor

Thanks for reading!

Top comments (3)

Collapse
 
superails profile image
Yaroslav Shmarov

Thanks for the guide! Since creating rails 8 apps, I've noticed the /script folder but didn't pay attention.
Great work on scriptor btw - I like the idea of being able to run scripts from a GUI in prod. Will try

Collapse
 
superails profile image
Yaroslav Shmarov

*will try the gem

Collapse
 
vdaluz profile image
Victor Da Luz

Thanks for this, I just started checking out Rails 8 and I'm looking into this script runner feature. I have always used rake tasks for this purpose but your gem looks very nice for data management.