rake taskの作り方と、意外とハマりがちな引数の扱い

Railsにて、コマンド一つで「Userアカウント」を作れるようにするrake taskを作ります。
引数を3つ持たせて「Userアカウント」を作成出来るコマンド、という簡単なものです。

$ bin/rake create_user:user[test_user,exmaple@example.com,password]

rake taskの作り方として、簡単にサンプルを作っていきます。

そして早速ですが、実際に動作させる時にハマった箇所を紹介してみます。

以下の3つのrake task 実行コマンドで正しく動作しないコマンドはどれでしょう?

$ bin/rake create_user:user[test_user1,test1@exmaple.com,password]
$ bin/rake create_user:user[test_user2, test2@exmaple.com, password]
$ bin/rake "create_user:user[test_user3, test3@exmaple.com, password]"

「rake task初心者」や、「シェルでの引数の扱い」があやふやな方は答えに確信が持てないと思います。
答えは記事の最後の方で。

スポンサーリンク

環境情報

rails (5.1.4)
ruby 2.4.2p198

rake taskを作る

rails g コマンドで「create_user」という名のrake taskを作成する

$ bin/rails g task create_user

これで、lib/tasks/以下にタスクが作られます。

lib/tasks/create_user.rake

rake taskの初期状態

コマンドを打ってファイルを作った初期状態はこのようになっています。

namespace :create_user do
end

rake task完成形

namespace :create_user do
  desc "ユーザー名、メールアドレス、パスワードを入力し、ユーザーアカウントを作成する"
  task :user, ['name','email','password'] => :environment do |_, args|
    User.create!(
      name:     args.name,
      email:    args.email,
      password: args.password
    )
    puts "#{args.name}を作成しました。"
  end
end

今回の完成形はこんな感じのrake taskです。早速動かしてみます。

実行する

rake taskが正しく作成されているか確認してから実行します。

$ bin/rake -T

(前略)
rake create_user:user[name,email,password] # ユーザー名、メールアドレス、パスワードを入力し、ユーザーアカウントを作成する
(後略)
$ bin/rake create_user:user[test_user,test@exmaple.com,password]
test_userを作成しました。

メッセージが出力され、DBに正しくデータが登録されているのを確認出来ればOKです。

問題

さて、冒頭の方に出した問題をもう一回出してみます。

この3つの中で正しく実行できない記述はどれでしょう?

1.

$ bin/rake create_user:user[test_user1,test1@exmaple.com,password]

2.

$ bin/rake create_user:user[test_user2, test2@exmaple.com, password]

3.

$ bin/rake "create_user:user[test_user3, test3@exmaple.com, password]"

答え

A. 2

引数にスペースを入れた場合うまく動かない

$ bin/rake create_user:user[test_user2, test2@exmaple.com, password]
zsh: bad pattern: create_user:user[test_user2,

「zsh: bad pattern: create_user:user[test_user2,」 というエラーを吐いてます。

解説

シェルでどう引数を処理するかによって変わる。
今回の場合だとbin/rake に対して一つの引数を渡せば動作する。

例:

bin/rake create_user:user[test_user1,test1@exmaple.com,password]

スペースがない場合で記述すると、bin/rakeに対して1つの引数の扱い(動作する)

bin/rake create_user:user[test_user2, test2@exmaple.com, password]

スペースありで記述すると、bin/rakeに
「create_user:user[test_user2,」「test2@exmaple.com]「password」
という3つの引数が渡されるため動作しない。

bin/rake "create_user:user[test_user3, test3@exmaple.com, password"

引用符でくくった場合は、bin/rakeに1つの引数の扱いになる(正しく動作する)

自分は意外とこれでハマって数時間消費しました・・・

参考

Ruby on Railsの rake taskの挙動について / teratail