edy hub

プログラミングやライフスタイルについて書き綴っています

Railsのテーブル定義書を吐き出したい

はじめに

プロジェクトメンバーにエンジニア以外の関係者がいるときに、テーブル定義書を用意することになった。

テーブル定義書とは?

方法

下記を参考にrakeタスクを作成する。

gist.github.com

とりあえず動かしてみる

lib/tasks内にrakeタスクを作成する。

lib/tasks/dbdoc.rake




エラーが発生!

def get_schema_info(klass)
    table = Table.new
    table.name = klass.table_name
    table.columns = []
    table.indexes = []
    table.comment = klass.connection.retrieve_table_comment(klass.table_name) if defined? MigrationComments

    # 省略
end

ここで、klass(つまりmodels配下の*.rbファイル)とデータベースの整合性が合わない場合に、table_nameでNo Method Errorが発生した。

確認してみると、google_place.rbというGoogleMap用に設けていたモデルファイルが存在していた。

また、appliaction_record.rbというファイルについては、klassがnilで返ってきた。

そのため、もともとの配列から削除してあげることにした。

task dbdoc: :environment do
    klasses = Dir["app/models/**/*.rb"].
      reject{|f| f["concerns/"] }.
      reject{|f| f["app/models/google_place.rb"]}. # 追加
      reject{|f| f["app/models/application_record.rb"]}. # 追加
      map{|f| f.gsub(/^app\/models\/(.+?)\.rb$/, '\1') }.
      map{|m| ActiveSupport::Inflector.camelize(m) }.
      map{|k| ActiveSupport::Inflector.constantize(k) }
    datum = klasses.map{|k| get_schema_info(k) }
    # 省略
end

これで綺麗なklassesの配列が出来上がった。

datum内を覗いてみると、

=> [#<struct Table
  name="hoge_table_names",
  comment=nil,
  columns=
      [#<struct Column name="id", type="bigint(20)", not_null=false, default=nil, primary_key=true, comment=nil>,
    #<struct Column name="hoge_id", type="int(11)", not_null=true, default=nil, primary_key=false, comment=nil>,
    #<struct Column name="huga_id", type="int(11)", not_null=true, default=nil, primary_key=false, comment=nil>,
    #<struct Column name="created_at", type="datetime", not_null=false, default=nil, primary_key=false, comment=nil>,
    #<struct Column name="updated_at", type="datetime", not_null=false, default=nil, primary_key=false, comment=nil>],
  indexes=[]>,
  #<struct Table
    name="contract_plans",
    comment=nil,
    columns=....

というような配列が返ってきた(良い感じ)

しかし、またもやエラーが発生

安堵していたのも束の間、別のエラーが発生した。

rake aborted!
NameError: uninitialized constant Axlsx

何やら不明なAxlsxがあるらしい。

Axlsxとは?

AxlsxはExcelファイルの出力用に用いるらしい。

qiita.com

これを参考にした。

対策

GemfileにExcelファイルを扱うためのGemを導入した。

gem 'axlsx'
gem 'zip-zip'

gem 'zip-zip'を含めないと、axlsxとの依存関係によりエラーが発生します。

これで動くだろう

rakeタスクを実行してみます。

$ bundle exec rake dbdoc:dbdoc

これで、xslxの拡張子付きのテーブル定義書が発行されました〜