Running and Destroying Rails
Did you know that you can undo a Rails generator with the “destroy” command? Or execute arbitrary code in a Rails app from a cronjob using “runner”? Here’s a quick introduction to “running” and “destroying” with Rails!
Undo rails generate with rails destroy
Sometimes (okay, I’ll admit, pretty often), I’ll make a typo or forget a column when running a big rails generate model
or scaffold
command. Now I’m stuck with an incomplete bunch of files that I need to fix or delete.
For example, pretend I tried to generate a Report model but misspelled the name column as naem
:
$ bin/rails generate model Report naem:string
invoke active_record
create db/migrate/20150721233558_create_reports.rb
create app/models/report.rb
invoke test_unit
create test/models/report_test.rb
create test/fixtures/reports.yml
Oops! To fix my mistake, I could edit all of these files to correct the misspelling, or I could just undo the rails generate
command and re-run it.
To undo, run the same command a second time, but replace generate
with destroy
.
$ bin/rails destroy model Report naem:string
invoke active_record
remove db/migrate/20150721233558_create_reports.rb
remove app/models/report.rb
invoke test_unit
remove test/models/report_test.rb
remove test/fixtures/reports.yml
It’s magic! My project is back to where I started, as if nothing happened. (If I had already run db:migrate
, then I would need to run db:rollback
first, then rails destroy
.)
Execute code with rails runner
Have you ever needed to execute Rails code from the command line? Maybe you need to write a cronjob to clean up some models with ActiveRecord.
The rake solution
Until recently I assumed a custom rake task was the best solution. Something like this:
- Write a rake task to do my ActiveRecord stuff
- Put code in
lib/tasks/mytask.rake
- Run
bundle exec rake mytask
in my crontab or wherever
Better: use rails runner
!
The runner
command is just like ruby -e
: it executes an arbitrary string of Ruby code. Unlike ruby -e
, however, it first boots your Rails app and then runs your code in the full Rails environment. It’s just like running code inside the interactive rails console
.
In other words, there is no need to write a Rake task. That’s unnecessary boilerplate.
An example
Let’s say we need a cronjob to delete records of our Report model that are more than 3 months old. How would we do that using rails runner
?
First let’s add a scope in our existing app/models/report.rb
to handle the ActiveRecord logic:
class Report < ActiveRecord::Base
def self.pending_deletion
where("updated_at < ?", 3.months.ago)
end
end
Now performing the deletion from either the crontab or the command line is super easy:
bundle exec rails runner -e production "Report.pending_deletion.destroy_all"
Note that you can specify the desired Rails environment using the -e
or --environment
option. Otherwise it defaults to development
(or $RAILS_ENV
, if set).
Shortcuts
Like other Rails commands, there are one-letter shortcuts:
rails d
→rails destroy
rails r
→rails runner
I hope you find these commands to be useful in your Rails projects! More information can be found in the official Rails command line guide.
You just read
Running and Destroying Rails
Did you know that you can undo a Rails generator with the “destroy” command? Or execute arbitrary code in a Rails app from a cronjob using “runner”? Here’s a quick introduction to “running” and “destroying” with Rails!
Share this post? Copy link
About the author
Hi! I’m a Ruby and CSS enthusiast, regular open source contributor, software engineer, and occasional blogger writing from the San Francisco Bay Area. Thanks for stopping by! —Matt