如何使用rails / rake在对象上添加PostgreSQL注释?

时间:2016-05-19 20:39:22

标签: rake rails-activerecord

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

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

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

我觉得这可能更像是一个功能请求而不是可以快速完成的事情。这是否已经可行,我该怎么做?

2 个答案:

答案 0 :(得分:1)

您应该能够在您需要的地方执行原始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,因此数据库注释(和其他不受支持的Postgres对象)将需要使用答案顶部显示的原始SQL解决方案。

答案 1 :(得分:1)

事实证明这比我想象的要容易。可以使用以下内容创建./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'])