Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

ジェネレーターとテンプレートでRailsアプリを効率的にブートストラップする方法

Railsの「電池込み(batteries-included)」なアプローチは、このフレームワーク最大の強みのひとつです。アプリケーションを素早く立ち上げられる手軽さでは他の追随を許さず、その理由のひとつがRailsのジェネレーターにあります。

Railsを使ったことがあれば、ジェネレーターにはきっとお世話になったことがあるはずです。新しいアプリケーションを作りたいならrails new。モデルやビューをまとめてスキャフォールドしたいならrails generate scaffold。このほかにも、開発を迅速に始めたりワークフローを効率化したりするためのコマンドが数多く用意されています。

しかし、既存のジェネレーターだけでは物足りないこともあります。コマンドの挙動をカスタマイズしたり、独自のジェネレーターを作成したりしたくなるかもしれません。本記事では、ジェネレーターについて詳しく見ていきます。特に、テンプレートを使って独自のRailsアプリケーションを構築する方法に焦点を当てます。

それでは始めましょう!

Railsジェネレーターとは?

PythonやJavaScriptでお馴染みのジェネレーター関数とは異なり、Railsのジェネレーターは「モノを生成する」ことに特化したカスタムThorコマンドです。

例はたくさんあります。新しいActiveRecordモデルを作成するモデルジェネレーター(rails generate model)や、新しいマイグレーションを生成するマイグレーションジェネレーター(rails generate migration)は頻繁に使うでしょう。さらにrails generate generatorというコマンドもあり、その名の通り——お察しの通り——新しいジェネレーター自体を作成します。

ジェネレーターは互いに呼び出すことができます。たとえばrails scaffoldは多数の他のジェネレーターを呼び出します。また、ファイルの作成・変更、gemのインストール、特定のrakeタスクの実行などを行うメソッドも提供されています。仕組みを理解するために、シンプルなモデルスペックジェネレーターを作ってみましょう。

Ruby on Railsで独自のジェネレーターを作成する

まず、以下のコマンドを実行します:

これにより/lib/generators/model_specにいくつかの新しいファイルが作成されます。lib/generators/model_spec/フォルダ内のmodel_spec_generator.rbを編集して、正しいディレクトリにモデルスペックファイルを作成できるようにしましょう:

templateコマンドはlib/generators/model_spec/templatesディレクトリ内のテンプレートファイルを探し、指定された場所——spec/modelsディレクトリ——にレンダリングします。このコマンドは、テンプレートファイル内のERB形式の変数を置き換えます。

source_rootを設定することで、ジェネレーターが参照するテンプレートファイルの場所を認識できるようになります。lib/generators/model_spec/templates/フォルダ内のテンプレートmodel_spec.rbは次のようになります:

このファイルを作成すれば、ジェネレーターを実行して新しいスペックファイルを生成できます。

多くのgemがこのようなジェネレーターを同梱しています。実際、私たちが作成したのはRspecが同梱しているジェネレーターの簡易版です。FactoryBotにはファクトリー用のジェネレーターがあり、他にも例は数多くあります。

各種gemに含まれるジェネレーターは、私たちが作ったものより洗練されています。引数を受け取れるようにしたり、rails scaffoldなどの既存のジェネレーターにフックしたりすることも可能です。詳しくはRailsジェネレーターの公式ドキュメントを参照してください。

つまり、ジェネレーターは既存アプリケーションのワークフローを簡素化する力を持っています。では、新しいアプリケーションのセットアップをカスタマイズするためにも使えるのでしょうか?

そこで登場するのがテンプレートです!

Ruby on Railsのテンプレート

名前の示す通り、テンプレートとはアプリケーションのセットアップをカスタマイズするためのファイルです。先ほど説明したテンプレートファイルと混同しないよう注意してください!内部実装としては、特定の目的を持ったジェネレーターにすぎません。これはテンプレートAPIを見れば明らかです。ジェネレーターと完全に同一ではありませんが、非常に似ています。

既存のテンプレートファイルがあれば、次のように使用できます:

ローカルファイルではなくURLを指定することもできます。これはアプリケーションテンプレートを共有できる点で特に便利です。

テンプレートを使用できるのはrails newの実行時だけではありません。すでにセットアップ済みのアプリにも、次のコマンドで後から適用できます:

テンプレートは非常に便利です。新しいアプリを作るたびに、同じgemを追加して同じ設定変更をする作業を自動化したいと思わない人はいないでしょう。独自のアプリケーションテンプレートを作るのはとても楽しい作業です——長期的に大きな時間節約にならなくても、です。

Railsで独自のテンプレートを作成する

ジェネレーターの基礎とテンプレートの使い方がわかったところで、セットアップ手順を自動化するシンプルなアプリケーションテンプレートを作成してみましょう。

Railsアプリのセットアップ方法は個人の好みによりますが、ここでは次のような流れを想定します:

  1. dotenv gemをインストールする
  2. 開発環境用の.env.developmentファイルを作成する
  3. データベース設定ファイルを環境変数を使うように変更する
  4. オプションでRspecをインストール・セットアップする

まずローカルファイルmytemplate.rbを作成し、gemコマンドでdotenvを追加します。

dotenv gemを追加したので、データベース設定を格納する.env.developmentファイルも作成しましょう。

create_fileを使うと、特定の内容を持つ新しいファイルを作成できます。このメソッドはThorが提供しているため、テンプレートやジェネレーターのドキュメントには記載されていません。fileというエイリアスも目にすることがあるでしょう。アプリケーションテンプレートはRails::Generators::AppGeneratorのコンテキストで評価され、まさにそこでfileエイリアスが定義されているのです。

app_name変数にはrails newの最初の引数が入ります。この変数を使えば、設定ファイルが生成されるアプリケーションと一致することを保証できます。

次に、環境変数を使ってデータベースに接続しましょう。create_fileコマンドでconfig/database.ymlを丸ごと上書きすることもできますが、ここではinject_into_fileを使って修正します。

after引数には文字列または正規表現を指定でき、コンテンツを挿入する位置を制御できます。

もちろん、この種の設定はSQLiteでアプリケーションを作成しない場合にのみ意味があります。options変数を使えば特定の引数の有無を確認できます。利用可能なオプションについては、Railsのappジェネレーターのソースコードを読むのがおすすめです。

最後に、ユーザーが必要に応じてRspecをインストールできるようにしましょう。ユーザー入力を受け取ってインタラクティブなテンプレートを作る方法はいくつかあります。yes?メソッドはユーザーに確認を求めるメソッドです:

gemメソッドはすでに紹介しましたが、generateafter_bundleは初登場です。

前述の通り、Rspecは独自のジェネレーターを追加します。テンプレートからこれらのジェネレーター(または他の任意のジェネレーター)を直接呼び出せます。ただし落とし穴があります——gemメソッドで指定されたgemは、テンプレートの処理が完了した時点でインストールされます。そのため、そうしたgemが提供するジェネレーターをgenerateで呼び出しても失敗します。だからこそ、after_bundleを使ってコマンドをコールバックとして登録する必要があるのです。

:締めくくる前に、ファイルの作成・変更についてひとこと。ここではcreate_fileinject_into_fileを使いましたが、選択肢は他にもたくさんあります。さまざまなテンプレートを読んでいるとcopy_filetemplateに出会うかもしれません。話をシンプルに保つためにここでは触れませんでしたが、より高度なテンプレートを作りたいなら、こうしたファイル操作メソッドの存在も知っておくべきです。

結果:完成したテンプレート

最終的なテンプレートは次のようになります:

このテンプレートは次のコマンドでテストできます:

または、カスタムデータベース設定を活用する場合はこちらです:

前述の通り、このファイルはGitHub Gistとして共有するのにぴったりです。自分のニーズに合わせて調整し、アップロードして、同僚や友人、そしてあなたのカスタムアプリテンプレートに関心のある人全員と共有しましょう😉。

Railsジェネレーターとテンプレートについてさらに学ぶ

言うまでもなく、ここで紹介したのは表面をなぞったにすぎません。

Railsアプリの書き方や開発の進め方には人それぞれの好みがあり、世の中には無数のジェネレーターやアプリケーションテンプレートが存在します。具体的なカスタマイズ方法については、それらを読むことで多くを学べます。Chris Oliver氏のJumpstartと、コミュニティによってキュレーションされたテンプレート集RailsBytesをおすすめします。

また、ThoughtbotのSuspendersは、私がRailsジェネレーターとテンプレートを深掘りするきっかけとなりました。私自身もアプリケーションテンプレート——Schienenzeppelin——を書きました。最新の状態ではありませんが、何かのインスピレーションにはなるかもしれません。

まとめ:Ruby on Railsのジェネレーターとテンプレートを始めよう

本記事では、Railsジェネレーターの基礎とその使い方を見てきました。独自のジェネレーターを作成して、新しいモデルスペックの作成を簡素化しました。

続いてテンプレートを掘り下げ、アプリケーションのセットアップをカスタマイズするシンプルなテンプレートの作り方を学びました。多少の手間はかかりますが、その見返りは十分にあります。自分でテンプレートを書くのが性に合わない場合でも、オンラインには選べる既存のテンプレートがたくさんあります!

楽しいテンプレートライフを!

P.S. Ruby Magicの記事をいち早く読みたい方は、Ruby Magicニュースレターを購読して、記事を見逃さないようにしてください!

ジェネレーターとテンプレートでRailsアプリを効率的にブートストラップする方法

Hans-Jörg Schnedlitz

ゲスト執筆者のHansはオーストリア・ウィーン在住のRailsエンジニアです。コーディングやコーディングに関する読書に大半の時間を費やし、時には自身のブログで執筆することもあります。画面の前に座っていないときは、たいてい山でクライミングを楽しんでいることでしょう。

Hans-Jörg Schnedlitzのすべての記事


  1. Rubyで例外発生時にローカル変数とインスタンス変数をログに記録する方法

    簡単には再現できないバグに悩まされたことはありませんか?アプリをしばらく使い続けたユーザーの環境でだけ発生し、エラーメッセージやバックトレースを見ても原因がさっぱり分からない——そんな経験を持つ開発者は多いはずです。 こうした場面で役立つのが、例外が発生する直前のアプリの状態をスナップショットとして記録しておく手法です。たとえば、すべてのローカル変数とその値の一覧を取得できれば、デバッグの強力な手がかりになります。実は、これは思ったより簡単に実現できるのです。 この記事では、例外発生時点でのローカル変数をキャプチャする方法を紹介します。ただし、最初に重要な注意点があります。ここで紹介するテ

  2. Minitestの仕組みをソースコードで徹底解説!Rubyテストフレームワークの内部動作

    Minitestとは? MinitestはRubyのテストライブラリで、TDD(テスト駆動開発)スタイルでコードのテストを書くためのツールです。 Railsのデフォルトのテストフレームワークであり、Railsの生みの親であるDHH(David Heinemeier Hansson)のお気に入りでもあります。 主な競合であるRSpecと比較して、シンプルでコード量が少ない点を評価してMinitestを選ぶ開発者も多くいます。 下の画像をご覧ください: ただし、この記事の目的は「どちらを選ぶべきか」「どちらが優れているか」を語ることではありません。 この記事で扱うのは、Minitestが実際にど