4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Fusic その2Advent Calendar 2019

Day 2

RailsのGeneratorGeneratorが便利すぎたので早く帰れる

Last updated at Posted at 2019-12-02

どうも、株式会社Fusicでプリンシパルエンジニアやってる南部です。この記事はFusic その2 Advent Calendar 2019の2日目の記事です。

経緯

エンジニアは怠惰であれ、という言葉は誰が言ったのか、知るよしもありませんが、私もその例にもれず、怠惰な人間です。
ルーチンで作るものは5秒でつくってしまって、本当に頭を使うべきものに時間を割きたいと思うのは私だけではないでしょう。

RailsにはGeneratorをGenerateするGeneratorGeneratorというものがあります。もう何を言ってるのかわかりませんが、とにかくそういうものがあるのです。

これを導入すると、ルーチンワークを5秒で終わらせる夢が叶います。
みなさんも是非お試しください。

GeneratorGeneratorでGeneratorのテンプレートを作ろう

$ bundle exec rails generate generator nantoka
      create  lib/generators/nantoka
      create  lib/generators/nantoka/nantoka_generator.rb
      create  lib/generators/nantoka/USAGE
      create  lib/generators/nantoka/templates

このようにlib/generators/nantokaの中にファイルやディレクトリが作られます。
本体になるのはnantoka_generatorです。

lib/generators/nantoka/nantoka_generator.rb
class NantokaGenerator < Rails::Generators::NamedBase
  source_root File.expand_path('templates', __dir__)
end

まず、試しにこんなコードを書いてみます。

lib/generators/nantoka/nantoka_generator.rb
class NantokaGenerator < Rails::Generators::NamedBase
  source_root File.expand_path('templates', __dir__)

  def step1
    puts "step1: #{self.name}"
  end

  def step2
    puts "step2: #{self.name}"
  end
end
$ bundle exec rails g nantoka hoge                                                                                                                                                                                                                            
step1: hoge
step2: hoge

おわかりの通りに、このGeneratorに実装されたメソッドが順番に実行されるようです。

ファイルを作る

ファイルを作るにはcreate_fileを使って実装します。

lib/generators/nantoka/nantoka_generator.rb
class NantokaGenerator < Rails::Generators::NamedBase
  source_root File.expand_path('templates', __dir__)

  def create_generator_test_file
    create_file "generator_test.txt", "これはgeneratorのテストです: #{self.name}"
  end
end

create_fileは第一引数がRailsのrootパスからの相対パスを指定し、第二引数はそのファイルに書かれる内容です。

$ bundle exec rails g nantoka hoge
    create  generator_test.txt
$ cat generator_test.txt
これはgeneratorのテストです: hoge

ちゃんとファイルができてますね。

テンプレートからファイルを作る

create_fileはちょっとした内容をファイルに出力するには便利ですが、コードを出力するには結構難ありです。
やっぱりテンプレートエンジンほしくないですか?ほしいですよね?
ほら、我らがERBがあるじゃないですか。

lib/generators/nantoka/nantoka_generator.rb
class NantokaGenerator < Rails::Generators::NamedBase
  source_root File.expand_path('templates', __dir__)

  def create_generator_test_file
    template "generator_test.txt.erb", "generator_test.txt"
  end
end
lib/generators/nantoka/templates/generator_test.txt.erb
this is test

<%= name %>

これを実行してみましょう。

$ bundle exec rails g nantoka hoge
    create  generator_test.txt
$ cat generator_test.txt
this is test

hoge

引数がほしい

引数がほしい?じゃあ、作ればいいじゃない。

lib/generators/nantoka/nantoka_generator.rb
class NantokaGenerator < Rails::Generators::NamedBase
  source_root File.expand_path('templates', __dir__)

  # 引数を追加
  argument :words, type: :array, default: []

  def create_graphql_schema
    template "generator_test.txt.erb", "generator_test.txt"
  end
end

lib/generators/nantoka/templates/generator_test.txt.erb
this is test

<%= name %>

<% words.each do |word| -%>
<%= word %>
<% end -%>
$ bundle exec rails g nantoka hoge arg-foo arg-bar
    create  generator_test.txt
$ cat generator_test.txt
this is test

hoge

arg-foo
arg-bar

実際何に使うか?

例えば、graphql-rubyを使ってスキーマ定義したりするとき、似たようなRubyのコードがいっぱい出てくると思います。
そういうときに、一つGeneratorをつくっておけば、あら簡単。
どこかでバグが見つかっても、作り直すことも簡単です。

時間を無駄に浪費して残業してしまうなんてことがなくなりますように。

まとめ

エンジニアとは自らの幸せを自ら掴み取る人間である

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?