YOSHINO日記

プログラミングに関すること

Herokuにpushする時にはまった: Rails needs superuser privileges to disable referential integrity.

エラーに関して

WARNING: Rails was not able to disable referential integrity.:00,  ETA: 00:00:00

This is most likely caused due to missing permissions.
Rails needs superuser privileges to disable referential integrity.

なぜエラーがでるのか?

1: Railsはテスト実行前にテストデータを削除する。

2: ここで外部キー参照がある場合、削除する順番が大事になってくる

3: Railsとしては実行前に一時的にALTER TABLE tablename DISABLE TRIGGER ALLしている

4: 上記のpsqlコマンドはsuperuserでなくては使えない

Ruby on Rails deleting fixtures with foreign keys - Stack Overflow

この記事いわくそう書いてあった。

そう考えると psotgresの該当ユーザーにsuperuser権限を与えればよいことになります。

terminal

$ su - postgres            
$ psql -l                     

$ psql
\du   
ALTER ROLE ユーザ名 WITH SUPERUSER;

このエラーに遭遇するのは二回目で、確かに、この方法で治るのではないかと思います。

不必要なあるいは不適切なモンキーパッチをあててないか?

不必要なあるいは不適切なモンキーパッチをあててないか?

あててました。

これが、僕の今回のケースの真の意味での原因でした。

以下のようなモンキーパッチをあてていたのでした。

RailsのActiveRecordでSQLite3/PostgreSQLのidをリセットする拡張 | EasyRamble

module ActiveRecord
  class Base
    def self.reset_pk_sequence
      case ActiveRecord::Base.connection.adapter_name
      when 'SQLite'
        new_max = maximum(primary_key) || 0
        update_seq_sql = "update sqlite_sequence set seq = #{new_max} where name = '#{table_name}';"
        ActiveRecord::Base.connection.execute(update_seq_sql)
      when 'PostgreSQL'
        ActiveRecord::Base.connection.reset_pk_sequence!(table_name)
      else
        raise 'Task not implemented for this DB adapter'
      end
    end
  end
end

削除して問題は解決するはずです。

でも、必要だからモンキーパッチを当てるはずです。たいていの人は。

Heroku で superuser privileges の問題をどのように解決するか?

僕の場合、モンキーパッチを削除することで無事、Herokuへのデプロイをすることができたのですが、

どうしても、現状のままHerokuへのデプロイをしたいという人もいるかもしれません。

Herokuでは、Postgresのユーザー権限の変更とかはできないので、この問題は深刻です。

実は今回の問題に関するPRが過去にだされて、マージされずにcloseしています。

stackoverflow.com

なので、僕の調べた範囲では、権限回りで今回のエラーがでて、なおかつ、Herokuのようなユーザー権限を変えられないような状況の場合、

上記の記事にあるようなモンキーパッチを追記することでこの問題を回避するしか無いのかなあと思います。