gpt4 book ai didi

ruby-on-rails - Heroku CI 与 rails 固定装置

转载 作者:行者123 更新时间:2023-12-04 06:06:14 25 4
gpt4 key购买 nike

我在 Rails 应用程序中使用 Heroku CI (Beta),当我的测试运行时,它们都失败并出现以下错误:

WARNING: Rails was not able to disable referential integrity.
This is most likely caused due to missing permissions.
Rails needs superuser privileges to disable referential integrity.
cause: PG::InsufficientPrivilege: ERROR: permission denied: "RI_ConstraintTrigger_a_5199633" is a system trigger

这与 rails 如何处理夹具记录的删除有关。他们没有试图找出记录被删除的顺序,而是简单地关闭保持参照完整性的触发器。

在 Heroku CI 上运行测试时,这不是一个选项。有没有人对此有适当的解决方案?

最佳答案

修复此问题的 Rails PR 已恢复:https://github.com/rails/rails/pull/27636

解决方法是猴子补丁:

# config/initializers/disable_referential_integrity.rb
require "activerecord/lib/active_record/connection_adapters/postgresql/referential_integrity.rb"
require "activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb"

添加到您的 lib/两个文件(来自 rails PR 的代码):
# lib/activerecord/lib/active_record/connection_adapters/postgresql/referential_integrity.rb
module ActiveRecord
module ConnectionAdapters
module PostgreSQL
module ReferentialIntegrity # :nodoc:
def supports_disable_referential_integrity? # :nodoc:
true
end

def disable_referential_integrity(&block) # :nodoc:
if supports_disable_referential_integrity?
if supports_alter_constraint?
disable_referential_integrity_with_alter_constraint(&block)
else
disable_referential_integrity_with_disable_trigger(&block)
end
else
yield
end
end

private

def disable_referential_integrity_with_alter_constraint
tables_constraints = execute(<<-SQL).values
SELECT table_name, constraint_name
FROM information_schema.table_constraints
WHERE constraint_type = 'FOREIGN KEY'
AND is_deferrable = 'NO'
SQL

execute(
tables_constraints.collect { |table, constraint|
"ALTER TABLE #{quote_table_name(table)} ALTER CONSTRAINT #{constraint} DEFERRABLE"
}.join(";")
)

begin
transaction do
execute("SET CONSTRAINTS ALL DEFERRED")

yield
end
ensure
execute(
tables_constraints.collect { |table, constraint|
"ALTER TABLE #{quote_table_name(table)} ALTER CONSTRAINT #{constraint} NOT DEFERRABLE"
}.join(";")
)
end
end

def disable_referential_integrity_with_disable_trigger
original_exception = nil

begin
transaction(requires_new: true) do
execute(tables.collect { |name| "ALTER TABLE #{quote_table_name(name)} DISABLE TRIGGER ALL" }.join(";"))
end
rescue ActiveRecord::ActiveRecordError => e
original_exception = e
end

begin
yield
rescue ActiveRecord::InvalidForeignKey => e
warn <<-WARNING
WARNING: Rails was not able to disable referential integrity.
This is most likely caused due to missing permissions.
Rails needs superuser privileges to disable referential integrity.
cause: #{original_exception.try(:message)}
WARNING
raise e
end

begin
transaction(requires_new: true) do
execute(tables.collect { |name| "ALTER TABLE #{quote_table_name(name)} ENABLE TRIGGER ALL" }.join(";"))
end
rescue ActiveRecord::ActiveRecordError
end
end
end
end
end
end

和第二个文件:
# lib/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
module ActiveRecord
module ConnectionAdapters
class PostgreSQLAdapter < AbstractAdapter

def supports_alter_constraint?
# PostgreSQL 9.4 introduces ALTER TABLE ... ALTER CONSTRAINT but it has a bug and fixed in 9.4.2
# https://www.postgresql.org/docs/9.4/static/release-9-4-2.html
postgresql_version >= 90402
end

end
end
end

关于ruby-on-rails - Heroku CI 与 rails 固定装置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43709491/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com