class Yaml2erd

Constants

DEFAULT_CONF
TABLE_HEADER
VERSION

Attributes

group_global_conf[RW]

Public Class Methods

new(yaml_file_path, conf_yaml_path) click to toggle source

TODO: nodesとglobalの違いみたいなの調査

# File lib/yaml2erd.rb, line 43
def initialize(yaml_file_path, conf_yaml_path)
  @yaml = ErYamlParser.new(yaml_file_path)
  @gv = Gviz.new
  @gv_id_map = GvIdMap.new

  @customized_conf = fetch_conf(conf_yaml_path)
  apply_conf(@customized_conf)
end

Public Instance Methods

file_save(save_path: '') click to toggle source
# File lib/yaml2erd.rb, line 77
def file_save(save_path: '')
  ext = :png
  dir = 'erd'
  filename = remove_ext(@yaml.yaml_file_path)

  if save_path.present?
    dir = File.dirname(save_path)
    filename = remove_ext(save_path)
    ext = File.extname(save_path).slice!(1..-1)
  end

  @gv.save "#{dir}/#{filename}", ext
end
write_erd() click to toggle source
# File lib/yaml2erd.rb, line 52
def write_erd
  # entityとrelation作成
  @yaml.model_list.each do |model|
    columns = @yaml.models[model].columns
    relations = @yaml.models[model].relations
    description = @yaml.models[model].description

    validate_columns!(model, columns)

    # TODO: addとrouteの違いはなんだろう
    # entityの枠(model)作成
    @gv.route @gv_id_map.enc(model)

    # entityの中身(tableタグ)作成、適用
    table_tag = create_table_tag(model, columns, description)
    @gv.node @gv_id_map.enc(model), label: table_tag

    # relation適用
    apply_relation(model, relations)
  end

  # group適用
  apply_grouping
end

Private Instance Methods

apply_conf(conf) click to toggle source
# File lib/yaml2erd.rb, line 105
def apply_conf(conf)
  # 適用
  @group_global_conf = conf[:group_conf]
  @nodes_conf = conf[:entity_conf]

  @gv.global conf[:global_conf]
  @gv.nodes @nodes_conf
end
apply_grouping() click to toggle source
# File lib/yaml2erd.rb, line 199
def apply_grouping
  # グループ内に適用するために再度@nodes_confをあてる
  nodes_conf = @nodes_conf
  group_conf = @group_global_conf

  # mapをもとにグルーピング
  @yaml.groups_map.each do |group_name, models|
    group_bgcolor = @yaml.groups_bgcolor_map[group_name.to_sym]
    alias_models = models.map do |model| @gv_id_map.enc(model) end

    @gv.subgraph do
      global group_conf.merge(label: group_name, bgcolor: group_bgcolor)
      nodes nodes_conf
      # model割り当て
      alias_models.each do |alias_model|
        node alias_model
      end
    end
  end
end
apply_relation(model, relations) click to toggle source
# File lib/yaml2erd.rb, line 188
def apply_relation(model, relations)
  # リレーションのマッピング
  return if relations.blank?
  relations.each do |relation|
    relation.each do |rel_type, rel_model|
      next if rel_type != :has_one && rel_type != :has_many
      @gv.edge "#{@gv_id_map.enc(model)}_#{@gv_id_map.enc(rel_model)}", @customized_conf[:arrow_map][rel_type]
    end
  end
end
convert_check_mark(val) click to toggle source
# File lib/yaml2erd.rb, line 170
def convert_check_mark(val)
  # TODO: 指定なし/指定ありtrue/指定ありfalseを考慮
  val.present? ? '✔︎' : ''
end
create_table_body(db_columns) click to toggle source
# File lib/yaml2erd.rb, line 146
def create_table_body(db_columns)
  table_body = ''
  db_columns.each do |db_column, db_column_info|
    db_column_logical_name = db_column_info[:logical_name].presence || ''
    db_column_description = db_column_info[:description].presence || ''
    db_column_options = db_column_info[:options].presence || {}

    # 表示する値とalignの指定
    table_columns = [
      { val: db_column,                                             align: :left },
      { val: db_column_logical_name,                                align: :left },
      { val: db_column_info[:type],                                 align: :left },
      { val: convert_check_mark(db_column_options[:primary_key]),   align: :center },
      { val: convert_check_mark(db_column_options[:foreign_key]),   align: :center },
      { val: convert_check_mark(db_column_options[:not_null]),      align: :center },
      { val: db_column_options[:default],                           align: :left },
      { val: nl2br(db_column_description),                          align: :left }
    ]

    table_body += create_table_line(table_columns)
  end
  table_body
end
create_table_header() click to toggle source
# File lib/yaml2erd.rb, line 137
def create_table_header
  table_header = '<tr>'
  TABLE_HEADER.each do |head|
    table_header += "<td bgcolor='lightblue'>#{head}</td>"
  end
  table_header += '</tr>'
  table_header
end
create_table_line(table_columns) click to toggle source
# File lib/yaml2erd.rb, line 179
def create_table_line(table_columns)
  table_line = '<tr>'
  table_columns.each do |table_column|
    table_line += "<td bgcolor='white' align='#{table_column[:align]}'>#{table_column[:val]}</td>" \
  end
  table_line += '</tr>'
  table_line
end
create_table_tag(db_table_name, db_columns, db_table_description) click to toggle source
# File lib/yaml2erd.rb, line 121
def create_table_tag(db_table_name, db_columns, db_table_description)
  table_tag = "<table border='0' cellborder='1' cellpadding='8'>"

  # DBのテーブル名
  table_tag += "<tr><td bgcolor='lightblue' colspan='#{TABLE_HEADER.size}'>#{db_table_name}</td></tr>"
  # ヘッダ(TABLE_HEADERから生成)
  table_tag += create_table_header
  # ボディ(DBのテーブルの各カラムのデータ)
  table_tag += create_table_body(db_columns)
  # フッタ
  table_tag += "<tr><td bgcolor='lightblue' colspan='#{TABLE_HEADER.size}'>#{nl2br(db_table_description)}</td></tr>"

  table_tag += '</table>'
  table_tag
end
fetch_conf(conf_yaml_path) click to toggle source
# File lib/yaml2erd.rb, line 93
def fetch_conf(conf_yaml_path)
  user_conf = {}
  if conf_yaml_path.present?
    File.open(conf_yaml_path) do |file|
      user_conf = YAML.safe_load(file.read).deep_symbolize_keys
    end
  end

  # ユーザ設定取り込んで、固定値をマージして返す
  DEFAULT_CONF.deep_merge(user_conf)
end
nl2br(str) click to toggle source
# File lib/yaml2erd.rb, line 175
def nl2br(str)
  str.gsub(/\r\n|\r|\n/, '<br />')
end
remove_ext(file_name) click to toggle source
# File lib/yaml2erd.rb, line 220
def remove_ext(file_name)
  File.basename(file_name, '.*')
end
validate_columns!(db_table_name, db_columns) click to toggle source
# File lib/yaml2erd.rb, line 114
def validate_columns!(db_table_name, db_columns)
  # ささやかなバリデーション
  return if db_columns.class == Hash
  p "#{db_table_name} columns error"
  exit
end