3

Sequel のような ORM を使用すると、モデルの列は接続されたデータベースによって定義されます。テーブルの列に関するドキュメントを入手するにはどうすればよいですか?

(続編ですがARも原理は同じだと思います):

この移行でテーブルを作成します。

Sequel.migration do
  up do
    create_table(:person) do
      primary_key :id
      String :name, :null=>false
    end
  end
  down do
    drop_table(:person)
  end
end

データベースに列の説明を追加する方法はありません (またはありますか?DB 固有の解決策はありません)。

対応するモデルは次のように定義されます

class Person < Sequel::Model
end

rdoc でドキュメントを生成すると、Person のドキュメントが「空」になり、列の説明が表示されません。

次のように、列に getter メソッドを追加できます。

class Person < Sequel::Model
  #Name of the person
  attr_reader :name
end

rdoc で説明を取得しますが、次の 2 つの問題があります。

  • Person#name常に nil で、DB への接続が失われます
  • そして、それが機能する場合、それは DRY 原則に違反しています。

すべての列のリストを追加できます。

#Columns:
# * name: Name of the person
# ...
class Person < Sequel::Model
end

しかし、再び:

  • これは DRY の原則に反します。
  • ゲッターメソッドのような利用可能なすべての列を見たいです。

annotate-gemを設立しました。ただし、この gem は以前のコメントを削除し、技術情報のみを追加します。コメントを追加できません。

datamapper、mongomaper、mongoid などの他のモデル フレームワークは、モデルの属性を直接定義します。(ソース) しかし、ORM を変更したくありません。

だから私の質問:列の説明を保存するためのベストプラクティスは何ですか?

4

1 に答える 1

0

これまでのところ答えはありません-おそらくベストプラクティスはありません。

その間に、 annotate-gemのアイデアを変更したアイデアがありました。

添付のスクリプトは、モデルのドキュメントを含む新しいrubyファイルを作成します。このrubyファイルはアプリケーションに追加されない可能性があります(モデルが壊れます)が、rdoc-callに追加することはできます。

次のスクリプトの最後に次のコードを追加します。

require 'your_application' #Get your model definitions

#Define ModelDocumentation with comments for the different fields
doc = ModelDoc.new(
  #reference with table.field
  'tables.field1' => 'field one of table tables',
  #reference with model.field
  'Table#field2' => "field two of table, referenced by model Table",
)
doc.save('my_doc.rb')

そして今、スクリプト:

#encoding: utf-8
=begin rdoc
Generate documentation file for Model, 
enriched with data from docdata
=end

=begin rdoc
Get all subclasses from a class.

Code from http://stackoverflow.com/a/436724/676874
=end
class Class
  def subclasses
    ObjectSpace.each_object(Class).select { |klass| klass < self }
  end
end  


=begin rdoc
Class to generate a Model-documentation

==Usage:

Write a script like this:

  require 'my_application' 
  require 'model_doc' #this script

  doc = ModelDoc.new(
    #reference with table.field
    'tables.field1' => 'field one of table tables',
    #reference with model.field
    'Table#field2' => "field two of table, referenced by model Table",
  )
  doc.save('my_doc.rb')

my_doc.rb can be included to your library. 
Don't load it to your application!
Only add it to your documentation with rdoc.
=end
class ModelDoc
=begin rdoc
Class to generate a Model-documentation.

Comments are a hash with.

Keys may be:
* Modelname#field
* tablename.field
=end
  def initialize( comments = {} )
    @comments = comments
  end

  def save(filename)
    docfile = File.new(filename, 'w')

    puts "(Re-)Generate #{docfile.path}"
    docfile << <<doc
=begin
This file is generated by #{__FILE__},
based on data from #{Sequel::Model.db.inspect}

Don't use this code in your implementation!
This code will overwrite your real model.


This is only for usage with rdoc.

=end
doc
    Sequel::Model.subclasses.each{|model|
      docfile << "\n\n#\n"
      docfile << "#Model for table '#{model.table_name}'\n"
      docfile << "#\n"
      docfile << "class #{model} < Sequel::Model\n"
      model.columns.each{|column|
        comment = @comments[[model, column].join('#')]
        comment = @comments[[model.table_name, column].join('.')] unless comment

        docfile << "  #\n  #table field #{field_description(model.table_name, column, model.db_schema[column]).join("\n  #* ")}\n"
        if comment
          docfile << comment.gsub(/^/, "  #")
          docfile << "\n"
        end
        #~ docfile << "  #\n#accessor generated by Model\n"
        docfile << "  attr_reader #{column.inspect}\n"
      }
      docfile << "end\n\n"
    }

    docfile.close
  end

  def field_description(table_name, column, db_schema)
    [
      "#{table_name}.#{column} (#{db_schema[:type]}/#{db_schema[:db_type]})",
      db_schema[:primary_key] ? "This is a key field" : nil,
      "Default is #{db_schema[:default] || 'undefined'}",
      #fixme: ruby_default
      "Null-values are #{'not ' unless db_schema[:allow_null]}allowed",
    ].compact
  end
end #ModelDoc

このスクリプトはSequelでのみ機能しますが、ARに適合させることができると思います。

于 2013-03-08T23:22:27.257 に答える