Help us understand the problem. What is going on with this article?

railsでrakeタスクがどのように定義されているか、:environmentがなぜ必要か、ざっくり調べた

More than 3 years have passed since last update.

rakeタスクを作っていて気になったことを調べました。

rake is 何?

rubyで実装されたビルドツール。
rakeファイルにビルドの定義を記述する。

rakeファイルの作成方法

$ rails g task test

基本的な記述方法

testl.rake
task default: %w[test]

task :test do
  ruby "test/unittest.rb"
end
ソースコード内の記述 役割
default タスク名
test 事前タスク
ブロック部分 実行されるタスクの中身

事前タスクとは

名前通り、ブロック部分に記述されたはタスクよりも先に実行されるタスクのこと。

rakeタスクが定義されるまで

プロジェクトディレクトリ直下にあるRakefile.

Rakefile
require File.expand_path('../config/application', __FILE__)

Rails.application.load_tasks
end

config/application.rbをrequire、Rails.application.load_tasksを実行します。

ruby/gems/2.1.0/gems/railties-4.2.7.1/lib/rails/engine.rb
def load_tasks(app=self)
  require "rake"
  run_tasks_blocks(app)
  self
end

さらにrun_tasks_blocksを実行しています。

ruby/gems/2.1.0/gems/railties-4.2.7.1/lib/rails/application.rb
def run_tasks_blocks(app) #:nodoc:
  railties.each { |r| r.run_tasks_blocks(app) }
  super
  require "rails/tasks"
  task :environment do
    ActiveSupport.on_load(:before_initialize) { config.eager_load = false }

    require_environment!
  end
end

事前タスクとして登録されることが多いenvironmentですが、ここで定義されていたんですね!

ruby/gems/2.1.0/gems/railties-4.2.7.1/lib/rails/railtie.rb
## スーパークラス
def run_tasks_blocks(app) #:nodoc:
  extend Rake::DSL
  each_registered_block(:rake_tasks) { |block| instance_exec(app, &block) }
end

def run_tasks_blocks(*) #:nodoc:
  super
  paths["lib/tasks"].existent.sort.each { |ext| load(ext) }
end

lib/tasks以下にあるファイルをロードすることにより、rakeタスクが定義されているようです。

:environmentの内容

ruby/gems/2.1.0/gems/railties-4.2.7.1/lib/rails/application.rb
def require_environment! #:nodoc:
  environment = paths["config/environment"].existent.first
  require environment if environment
end

config/environment を require しています。

config/environment.rb
# Load the Rails application.
require File.expand_path('../application', __FILE__)

# Initialize the Rails application.
Rails.application.initialize!

Rakeタスクを使ってActiveRecordのモデルなどを扱いたいとき、
事前タスクとして:environmentをわたす必要があるのは、この為だったんですね。

mt2
ゲーム会社勤務のエンジニア。 Ruby,Ruby on Rails,Unity...インフラ(AWS)勉強中
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away