Is there any "official" way to organize one-off scripts?

Hi, I’ve seen some people considering how to organize one-off scripts in Rails.

I know Rake tasks are one way but they can be executed multiple times.
Scripts in migrations can be good for modifying data, but they’re executed in development environment which generally is not desired.

Maybe I missed it, but is there any official way to organize them? Do you think we need some small framework for one-off scripts or scripts/batches in general?

2 Likes

Rake’s probably the solution for this. Once you’ve run the task, you can remove the task from your code (or keep it, in case you need it later).

Running scripts in production without testing them in development is likely not going to end well.

Just make a Rake task, and run it once manually.

if you are talking about data migrations, there is a gem for this which might be helpful GitHub - theSteveMitchell/after_party: Automated post-deploy tasks for Ruby/Rails. Your deployment is the party. This is the after party . We use that. But you will have to run an extra rake after_party:run after migrations in your deployments.

Using Rake is probably the simplest solution, but I don’t like the extra cost to confirm it’s actually executed in production once and commit deletion of the task.
Also, I’m afraid Rake task is not so easy to test (I know it’s off topic).

Thanks for sharing a gem. I know other gems such as:



And that’s actually the point: There are several, similar-but-not-the-same gems out there to migrate data in Rails. I suspect it indicates the need of “official” way.

1 Like

At work, we have to frequently run on-off scripts that are part of on-call tasks.

We use rails runner mode rails r path_to_script.rb .

As for organizing we maintain on-call wiki for common one-off scripts, if they become more frequent, we move them to oncall_helper module as part of code or spin a feature around it with parameters exposed for controlling it.

2 Likes

I understand your approach using runner, but do you think manually maintaining wiki for one-off scripts work well?

I came up with the idea that if we have conductor we might be able to manage and run one-off scripts from web browsers, which is cool :laughing:

Yes, that is not the ideal way.
But wiki is for scripts that need to be run occasionally.
Example: Other team uploaded wrong data, we need to clean that up, or other manually work.

If it’s becomes frequent we fix the underlying issue or introduce it in inside the code.

We use script/migrate/* at Basecamp. It’s just a basic script that starts with:

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

We also have script/benchmark/* and others like that. You could well have script/cleanup/* or whatever.

6 Likes

Thanks, but unfortunately script directory is not generated by default anymore. I’m seeing many people reinvent this wheel with several gems and I guess that’s partly because Rails doesn’t provide any default way.

Maybe just adding script directory to Rails default directories will solve this problem.

(Btw I don’t like the idea of putting all scripts into bin directory since it mixes auto-generated scripts and hand-crafted ones)

1 Like

Oh, I hadn’t even realized that. Yes, I would support bringing back script/ as a default directory, and showing that this is a good usage.

7 Likes

I have opened a PR to add the script folder into a new rails app: Adds ./script folder to a new rails app by hahmed · Pull Request #39552 · rails/rails · GitHub

5 Likes

Here’s what we do - we put all the logic into service classes because we never know which piece of business logic will ultimately end up as an API vs. a rake task, so testability is not an issue.

All we do additionally is maintain a namespace called one_time under which we put all the one-off migration tasks.

It helps, because it adds a consistent way to invoke all one-off scripts, a place where we know we can find them, list them out with a rake -T | grep one_time and its comfortable to use for release notes.

1 Like