@ledsun blog

Hのキーがhellで、Sのキーがslaveだ、と彼は思った。そしてYのキーがyouだ。

ActiveRecordを継承したクラスからUMLクラス図を作る

DBの情報からER図を生成するツールはいくつかあります。 またUMLを生成するツールもあります。

同じような感じで、UMLActiveRecordから取得します。 この手法の利点はメソッド情報がとれることにあります。

model_name = ARGV[0]
class_name = Object.const_get model_name
puts '@startuml'
puts "class #{class_name} {"

class_name.columns.each do |c|
  printf "  %8s %s\n", c.type, c.name
end

class_name.public_instance_methods(false).each do |m|
  method_parameters = class_name.new.method(m)
                                .parameters
                                .filter{ |a| a[0] == :req }
                                .map { |a| a[1]}.join(', ')
  printf "  %s(%s)\n", m.to_s, method_parameters
end

puts '}'

class_name.reflect_on_all_associations(:belongs_to).each do |a|
  puts "#{class_name} --* #{a.name.to_s.classify}"
end
class_name.reflect_on_all_associations(:has_many).each do |a|
  puts "#{class_name} *-- #{a.name.to_s.classify}"
end
class_name.reflect_on_all_associations(:has_one).each do |a|
  puts "#{class_name} -- #{a.name.to_s.classify}"
end

puts '@enduml'

ActiveRecordの情報が欲しいので、次のようにrails runnerから起動します。

~ bin/rails runner class_diagram.rb Dictionary

次のようなPlantUMLのテキストを出力します。

@startuml
class Dictionary {
   integer id
    string name
      text description
   integer user_id
   integer entries_num
  datetime created_at
  datetime updated_at
   boolean public
    string license
    string license_url
      text no_term_words
      text no_begin_words
      text no_end_words
   integer tokens_len_min
   integer tokens_len_max
     float threshold
    string language
  editable?(user)
  autosave_associated_records_for_jobs()
  validate_associated_records_for_jobs()
  undo_entry(entry)
  administrable?(user)
  num_gray()
  num_white()
  num_black()
  create_a_black_entry(entry)
  add_entries(hentries)
  new_entry(label, identifier)
  empty_entries()
  sim_string_db_dir()
  tmp_sim_string_db_path()
  compilable?()
  update_stop_words()
  autosave_associated_records_for_user()
  autosave_associated_records_for_associated_managers()
  validate_associated_records_for_associated_managers()
  compile!()
  simstring_method()
  narrow_entries_by_label(str)
  narrow_entries_by_label_prefix(str)
  narrow_entries_by_label_prefix_and_substring(str)
  narrow_entries_by_identifier(str)
  autosave_associated_records_for_associations()
  autosave_associated_records_for_entries()
  validate_associated_records_for_associations()
  validate_associated_records_for_entries()
  search_term(ssdb, term)
  sim_string_db_path()
  additional_entries()
  to_param()
}
Dictionary --* User
Dictionary *-- Association
Dictionary *-- AssociatedManager
Dictionary *-- Entry
Dictionary *-- Job
@enduml

https://planttext.com/ などで、で画像に変換すると次の図が得られます。

f:id:ledsun:20210525234037p:plain
DictionaryモデルのUMLクラス図

この図を見て嬉しいかどうかは難しいところです。

参考