IT・技術研修ならCTC教育サービス

サイト内検索 企業情報 サイトマップ

研修コース検索

コラム

Ruby & Rails

CTC 教育サービス

 [IT研修]注目キーワード   Python  UiPath(RPA)  最新技術動向  Microsoft Azure  Docker  Kubernetes 

第21回 RailsのDB周りを快適に! ~『Annotate』『MigrationComments』の紹介~ (藺藤卓実) 2015年11月

 皆さん、こんにちは。 藺藤です。
 今年、弊社には20名を越える新人が入社しました。 ゼネットの場合、新入社員は入社後約3ヶ月の間プログラム言語習得の研修(JavaやRuby, HTML, JavaScript等)や、各プロジェクトに参加してのOJTを行います。 そして研修期間を終えた後、彼ら・彼女らは各々業務に従事するようになります。 私が参加しているプロジェクトにも新たに2名が加わりました。 まだまだ頼りない部分も少なくないのですが、日々の業務の中でぐんぐんと成長していることも実感しており、頼もしくもあります。
 何も新人達に限ったことではありませんが、新しいプログラム言語を習得する際には、どこかのタイミングで必ず、英文のドキュメントやリファレンスを読むことになるかと思います。 しかしながら、やはりどうしても「英語は苦手だ」と溢す人もいるのが実情です。 この点、幸いなことにRubyには日本語で書かれた優れた解説やドキュメントが多いようです。 これもまた、魅力の一つと言えるのではないでしょうか。

 さて、Webアプリを素早く作れるRuby on Railsですが、開発が進み、モデルやテーブルの数が増えてくると、次第にDB周りを把握することが難しくなってきませんか?
 今回は、そんな時にプログラマを助けてくれる2つのGemを紹介します。 2つとは「Annotate」(*1)と、「MigrationComments」(*2)というものです。 どちらのGemも、導入・利用共に非常に簡単ですが、実際に使ってみるとその便利さを実感できるのではないでしょうか。

 それでは、サンプル・アプリケーションを作りながらこれらのGemを見ていきましょう。
今回はサンプルとして『Small world』(小さな世界)というアプリを作成していきます。 動作確認環境はCentOS、Ruby 2.1.5p273、そして Rails 4.2.1です。
 『Small world』には、登場人物を表す「Character」と、出身地(国)を表す「Region」の2つのモデル(テーブル)が存在します。 「Character」は一つの出身地を持ちます。 「出身地を持つ」という条件は、データベース設計としては外部キーを利用した「1対N」の関係性で表現します。
 このような設定の下、サンプルアプリは以下のコマンドを実行することで作成できます。

rails new small_world

cd small_world rails g scaffold  region  name:string    rails g scaffold  character  name:string region:references

scaffold コマンド実行後には、DBを構成するために「rake db:migrate」コマンドも実行しておきましょう。 
 さて、ご存じの通り、ActiveRecord (Rails)においては scaffold 直後のモデル定義にはほとんど何も書かれていません。 モデルとして振る舞うための基本的なメソッド類は、ActiveRecord::Baseを継承した子クラスを作ることで手に入れることができるのでした。 参考までに、scaffold直後のCharacterモデルの定義ファイルを掲載します。 コードは僅か3行となっています。(もちろん、これでも最低限の動作はするのですが。)

[app/models/character.rb]

class Character < ActiveRecord::Base
    belongs_to :region
end

それでは、さっそく「Annotate」を紹介してゆきます。

Annotate

 アノテートとは"注釈"という意味です。 Javaを触ったことのある方にはお馴染みの言葉ではないでしょうか。 このGemは、マイグレート・ファイル中に記述したテーブル定義に基づき、プログラム上の然るべきところに注釈(コメント)を追加してくれます。
 まずはGemfileの最終行に、以下の一文を追記します。

[Gemfile]

(初期設定されているGem;ここでは省略します) 

gem 'annotate'  # この部分を追加

 端末から「bundle install」コマンドを実行し、Annotateをインストールしましょう。 Gemのインストールに成功したら、続けて「annotate」コマンドを実行します。

bundle install

annotate #=> Annotated (2): Region, Character

 「annotate」コマンドが成功すると、2つのモデル(Region, Character)に対してアノテーション(注釈の追加)が行われた旨が表示されます。(*3) この段階で「app/models/characters.rb」を見てみましょう。 Rubyのコメントを利用して、モデル(テーブル)の属性名に関する情報が追加されているはずです。

[app/models/character.rb]


# == Schema Information
#
# Table name: characters
# 
# id            :integer        not null, primary key
# name          :string
# region_id     :integer
# created_at    :datetime       not null
# updated_at    :datetime       not null
#

class Character < ActiveRecord::Base belongs_to :region end

 個人的には、テーブル(カラム)に対する制約等がコンパクトな形で表現されており見やすいと思うのですが、いかがでしょうか?
アノテーションの自動追加の対象はモデルファイルだけに留まりません。 同様の記述は、モデル(テーブル)と密接に関わりのあるフィクスチャ・ファイルや、モデルのテストコードにも追加されます。 ぜひ、お手元の環境でご確認ください。

 Annotateを利用することで自動的にコメントが追加されましたが、一つ使用上の注意があります。 「annotate」コマンドによって自動生成されたコメントと、ユーザが(通常は、手動で)追加したコメントを区別するため、annotateでは"空行"を利用しています。 クラス定義の直前の行等にコメントを残したい場合には以下の点に気をつけてください。

  1. 自動生成部分の直後に空行が存在している状態を保つこと
  2. 空行の一つ下の行から、実際に残しておきたいコメントを書くこと

具体的には次のような形でコメントを記述します。

[app/models/character.rb]


# == Schema Information
#
# Table name: characters
# 
# id            :integer        not null, primary key
# name          :string
# region_id     :integer
# created_at    :datetime       not null
# updated_at    :datetime       not null
#

# 残したいコメントはここより下に書く(すぐ一つ上の空行を削除してはいけない) # この部分には、例えば以下のようなコメントを残すことができます: # # = Character モデル # # 「Small world」の登場キャラクターを表すモデルです class Character < ActiveRecord::Base belongs_to :region end

 アノテーションを追加するために、先ほど私たちは「annotate」コマンドを直接入力し、実行しました。 ですが、テーブル(モデル)のカラム名や、カラムの型、制約等が変更された場合に、自動的に情報更新してくれると非常に便利ですね。 このためには、以下のコマンドを実行してください。(初めに一度だけ実行します)

rails g annotate:install
#=> create  lib/tasks/auto_annotate_models.rake

 何か新たなファイルが作られたようですね。 開発中にテーブル定義を記述するマイグレート・ファイルに変更を加えた際は、開発用データベースを作り直すために「rake db:migrate:reset」コマンドを利用するかと思います。 新たに作成されたrake ファイルのおかげで、ちょうどマイグレート・リセットされるタイミングでアノテーションの内容見直しを行ってくれるようになります。 
このため、新規Railsプロジェクトを作成した直後に上記のインストール・コマンドを実行しておけば、マイグレート・ファイルの記述内容と同期した適切なコメント(アノテーション)を維持しながら開発を進めてゆくことができます。

MigrationComments

 さて、後半は「MigrationComments」を紹介します。 「MigrationComments」はその名の通り、マイグレーションファイル中に(開発者向け情報としての)コメントを追加できるよう、機能拡張してくれるGemです。 「MigrationComments」を利用して記述されたコメントは、RDBMS自体が「カラムに対するコメント付与機能」を持っている場合、実際のデータベースにも反映されます。 また、前半で紹介した「Annotate」と連動することで、モデルファイルやフィクスチャ・ファイル、テストコード・ファイルに対しても同じコメントを表示できます。 
利用例としては、以下のようなケースが挙げられます。

  1. 英語のカラム名(または物理名)と日本語名(または論理名)を明記する
  2. 扱いに注意の必要なカラムに適切な情報を付与しておく
  3. Rails 4.1 で導入されたenumを利用する際、数値と意味の対応関係をメモする

 この他にも色々と活用できるかもしれませんね。 「こんな使い方があるよ!」というアイディアがありましたら是非教えていただきたいと思います。 
私たちの場合は、①の使い方が最も活用されているように思います。 (日本語・英語共に)適切な名称として使用されるべき言葉が、普段、開発陣が一日のうち一番長い時間目にしているソースコードの中に示されていることで、簡易的にではありますが用語の統一を図れています。 また、冒頭の話にも関わりますが、「どうしても英語だけは苦手だ」という方にもフレンドリーですよね。

 それでは早速インストールします。 まずはGemfileに以下の一文を追加し、「bundle install」コマンドを実行します。

[Gemfile]

(初期設定されているGem;省略します)

gem 'annotate' gem 'migration_comments' # この行を追加

 コメントの追加はマイグレート・ファイルに対して行います。 使用例として、今回のサンプルプログラムの中のCreateCharacters クラスに対してコメントを追加してみます。 オレンジ色で示されている部分が、記述を追加した部分になります。

[db/migrate/YYYYMMDDHHMMSS_create_characters.rb]

class CreateCharacter < ActiveRecord::Migration
  def change
    create_table :characters, comment: '登場人物' do |t|
      t.string  :name, comment: '名前'
      t.references  :region, index: true, foreign_key: true,
        comment: 'FK(regions.id)'

t.timestamps null: false end end end

 上のサンプルコードの中で、"comment: "という部分が今回追記したコメントです。 ここでは例として

  1. テーブル名(日本語表記)に対するコメントを記述する場合
  2. カラム名(日本語表記)に対するコメントを記述する場合
  3. 外部キーが、(1)どのテーブルの(2)どのカラムを参照するのかを明示する場合

の3つのパターンを行ってみました。 (実際には②と③の使い方を同時にやることはないと思いますが、ここではあくまで例ということでご了承ください。)

 このようにして追加したコメントは、一度マイグレート・リセットを行うことで反映させることができます。 実際に「rake db:migrate:reset」コマンドを実行してみると、コメントを追加した character に関して再度アノテーションが行われたことを確認できます。

rake  db:migrate:reset
#=> Annotated (1): Character

 アノテーションによって変化した部分を見てみましょう。 Characterモデルを見てみます。 先ほどの記述によって変更された部分を再びオレンジ色で示します。

[app/models/character.rb]


# == Schema Information
#
# Table name: characters # 登場人物
# 
# id            :integer        not null, primary key # 登場人物
# name          :string                               # 名前
# region_id     :integer                              # FK(regions.id)
# created_at    :datetime       not null
# updated_at    :datetime       not null
#

# = Character モデル # # 「Small world」の登場キャラクターを表すモデルです
class Character < ActiveRecord::Base belongs_to :region end

 期待通り、「テーブル名(日本語表示)」「カラム名(日本語表示)」「外部キーの参照先情報」をそれぞれ表示できました。 ただ、ご覧になっていただくとわかる通り、"id"列に関しては"ID"とはならず、先ほど指定したテーブル名があたかもカラム名であるかのように扱われていますね。

 このようにして作成したコメントは、テーブル(カラム)に対するコメント機能を持つDBMSあれば、実際のDBの中にも反映させることができます。 作者の方のGitHubページには、現在のところ 「PostgreSQL」「MySQL」「Sqlite」はサポートされているとのことです。 私の環境でも、「MySQL」及び「Sqlite」ではそれぞれ機能していることを確認できました。

まとめ

 今回はRailsでモデル・DB周りの開発を支援してくれる2つのGem「Annotate」と「MigrationComments」を紹介しました。 
ユーザに直接的に何らかの機能を提供しないツール類は、ともすれば軽んじられがちなようにも思えます。 しかしながら、開発を支援してくれるツール類を上手に使いこなせれば、結果としてより良いプロダクトやサービスを作り出すことに注力しやすくなるのではないでしょうか。 どちらも有名なGemのようですので既にご利用中の方も多いかと思いますが、まだ試したことの無い方は是非一度使ってみてください。(*4)

それでは、Enjoy Ruby!

(注釈)

*1 : 「Annotate」https://github.com/ctran/annotate_models

*2 : 「MigrationComments」https://github.com/pinnymz/migration_comments

*3 : 筆者の環境では「annotate」コマンド実行時に警告が表示されました。 ただ、実行自体は特に問題なくできているようです。

*4:ちなみに筆者の場合、今回紹介したものは「rails newした後、取り敢えず入れておくGemリスト」の中の一部です。

 


 

 [IT研修]注目キーワード   Python  UiPath(RPA)  最新技術動向  Microsoft Azure  Docker  Kubernetes