Techioz Blog

Railsバージョンアップデート後の心理エラー

概要

最近、クライアントのアプリケーションを Rails 4 から Rails 5 に更新しました。 ただし、テスト スイートを実行した後、オブジェクトを作成しようとすると次の問題が発生しました。

       Failure/Error:
         @ens_response = EnsResponse.create!(
           edi_request_body:    @response.edi_request_body,
           edi_body:            @response.edi_data,
           reject_reason:       @response.attributes.try(:[], :reject_reason).try(:[], :text),
           response_attributes: @response.attributes
         )
       
       Psych::DisallowedClass:
         Tried to load unspecified class: Policy

ここで、Policy は app/models/ フォルダー内のモデルです。

YAML の読み込みを次のように変更してみました。

      @service_hash ||= YAML.load_file(
        Rails.root.join('config', 'mcp_services.yml'),
        permitted_classes: [Policy ],
        aliases: true
      )[Rails.env]

しかし、それは無駄でした。

また、次の行を使用するように application.rb ファイルを変更してみました。

    config.active_record.yaml_column_permitted_classes = [
      Symbol,
      ActiveSupport::HashWithIndifferentAccess,
      ActionController::Parameters

しかし、エラーが発生しました:

Failure/Error: require File.expand_path("../../config/environment", __FILE__)

NoMethodError:
  undefined method `yaml_column_permitted_classes=' for ActiveRecord::Base:Class

この問題の原因は何か考えられますか? ローカルの psych はバージョン psych (デフォルト: 3.0.2) で、レールは gem ‘rails’、‘5.2.8’ にあります。

前もって感謝します! :)

解決策

危険な簡単なハックは、これを application.rb に設定することです…

  config.active_record.use_yaml_unsafe_load = true

さらに複雑なのは、config/initializers にイニシャライザを追加することです。イニシャライザは、yaml をロードするときにどのクラスを許可するかを Rails に指示します。

config/initializers/yaml_loader.rb

Psych::ClassLoader::ALLOWED_PSYCH_CLASSES = [Policy,
                                                  ActionController::Parameters,
                                                  ActiveSupport::HashWithIndifferentAccess,
                                                  ActiveSupport::TimeWithZone,
                                                  ActiveSupport::TimeZone,
                                                  DateTime,
                                                ]
    
    module Psych
      class ClassLoader
        ALLOWED_PSYCH_CLASSES = [] unless defined? ALLOWED_PSYCH_CLASSES
        class Restricted < ClassLoader
          def initialize classes, symbols
            @classes = classes + Psych::ClassLoader::ALLOWED_PSYCH_CLASSES.map(&:to_s)
            @symbols = symbols
            super()
          end
        end
      end
    end