如何在带有 rails/rake 的对象上添加 PostgreSQL 注释?

How to add PostgreSQL comments on objects with rails/rake?

我想在使用 rake 时对数据库本身、表等对象添加注释。例如,当我发出 rake db:create 时,我想通过 PostgreSQL 扩展 SQL 语句自动添加评论(如果适配器不直接支持这个),比如

COMMENT ON DATABASE myapp_development IS 'Rails DB for project at c:/some/path/myapp/';

如果可能(通过提取 RDoc?)表和列,我希望 ActiveRecord::Migration 有类似的行为。

我突然想到,这可能更像是一个功能请求,而不是可以快速完成的事情。这已经可以做到了吗?我该怎么做?

您应该能够只在需要的地方执行原始 SQL。试试这个:

sql = "COMMENT ON DATABASE myapp_development IS 'Rails DB for project at c:/some/path/myapp/';"
records_array = ActiveRecord::Base.connection.execute(sql)

请注意,如果需要,您可以使用字符串插值(例如 "#{value}")来包含变量值。您拥有 Ruby 的所有表达能力,并且能够 运行 任何您需要的母语 SQL。

MigrationComments gem 为迁移对象的评论提供内联支持。要安装它,只需将其添加到您的 Gemfile:

gem 'migration_comments'

安装后,您可以包含两个内联注释:

def self.up
  create_table :users, comment: "User records are stored in this table." do |t|
    t.string :canonical_email, comment: "This column contains the email address that has been URL decoded and lowercased, to ensure system-wide uniqueness"
  end
end

和独立评论更改:

def self.up
  change_table :users do |t|
    t.comment "User records are stored in this table."
    t.change_comment :canonical_email, "This column contains the email address that has been URL decoded and lowercased, to ensure system-wide uniqueness"
  end
end

您可以找到 PgComment gem,它会让您使用类似 ActiveRecord 的语法进行评论。只需将此添加到您的 Gemfile:

gem 'pg_comment'

而且您将能够像这样做很酷的事情:

set_table_comment :users, "User records are stored in this table."
set_column_comment(:users, :canonical_email, "This column contains the email address that has been URL decoded and lowercased, to ensure system-wide uniqueness")

不幸的是,没有 set_database_comment 和 gem,因此数据库注释(和其他不受支持的 Postgres 对象)需要使用原始的 SQL 解决方案,显示在顶部回答。

事实证明这比我想象的要容易。可以创建 ./lib/tasks/annotate_db.rake,例如,从 Rails template file,具有以下内容

namespace :db do
  def update_db_comment
    Rails.configuration.database_configuration.each do |key, hash|
      db = hash['database']
      if not db.nil?
        sql = "COMMENT ON DATABASE #{db} IS 'Rails #{Rails::VERSION::STRING} #{key} DB for project at #{Rails.root} on #{Socket.gethostbyname(Socket.gethostname).first}';"
        # puts sql
        records_array = ActiveRecord::Base.connection.execute(sql)
      end
    end
  end

  task :create do
    update_db_comment
  end
end

# Rake::Task['db:create'].enhance(['db:set_db_comment'])