If you’ve been working with Rails for a while, you must have come across Rake. In fact, the very first post on this blog was a brief introduction to Rake. Written by the late Jim Weirich (my Ruby hero), Rake is to Ruby what make is to C. It’s very easy to create custom Rake tasks to simplify your development workflows. Rails even provides a generator (
rails g task) to create them for you.
However, one question that many new Rails developers have when learning Rails is how to access the Rails models in a Rake task, which is very useful for running some application logic or performing database queries via the command line. This article shows how to do it.
:environment task as the dependency for your custom task. It's that simple.
task count_users: [:environment] do puts User.count end
That's it. Now you can access any models in the task.
Here’s a simple Rake task that tries to use an ActiveRecord model named
# lib/tasks/count.rake desc "count the number of users in the system" task :count_users do puts User.count end
If I try to run this Rake task as it is, Rails throws a
NameError, as it doesn’t know what
User refers to. It has no idea about the context of our Rails application. No constants have been loaded.
$ bin/rails count_users rails aborted! NameError: uninitialized constant User puts User.count ^^^^^^^^^^^^^^^
To make the ActiveRecord models available in the Rake tasks, we must tell Rails to load the environment before running the task. This is similar to what happens when you launch the Rails console.
Loading the Rails environment gives you access to the ActiveRecord models, database, and much more.
Rails provides an
:environment task to load the environment. In Rake terminology, your task is dependent on the
:environment task, as it must be performed before your task.
# lib/tasks/count.rake desc "count the number of users in the system" task count_users: [:environment] do puts User.count end
Now you can access the
User model in the rake task without any errors.
:environment task is defined in the
railties/lib/rails/application.rb file. All it does is load the
config/environment.rb file in your application, which is what Rails does when you launch your application.
Here's a simplified version of the underlying code.
task :environment do require_environment! end def require_environment! # :nodoc: environment = paths["config/environment"].existent.first require environment if environment end
environment.rb file will first require the
application.rb file and then call the
initialize method on your application. This is exactly how your Rails application boots up when you launch it.
# config/environment.rb # Load the Rails application. require_relative "application" # Initialize the Rails application. Rails.application.initialize!
And that's how you can access your Rails models inside a Rake task.
I hope you found this article useful and that you learned something new.
If you have any questions or feedback, didn't understand something, or found a mistake, please leave a comment below or send me an email. I look forward to hearing from you.
Please subscribe to my blog if you'd like to receive future articles directly in your email. If you're already a subscriber, thank you.