在rails 5升级后,Activerecord存储仅返回空哈希

时间:2017-08-03 13:51:26

标签: activerecord rails-activerecord ruby-on-rails-5

我正在将rails 4.2应用程序升级到rails 5.其中一个模型使用ActiveRecord :: Store。在升级后检索记录时,所述存储只返回一个空哈希。我不知道为什么会发生这种情况,并且无法在更改日志中找到任何内容。所以任何帮助和解释都将不胜感激。

这是rails 4控制台的输出:

=> #<StoredDataQuery ..., config: {"start_date"=>6, "end_date"=>0, ...>

和rails 5:

=> #<StoredDataQuery ..., config: {}, ...

psql输出:

development=# SELECT config FROM stored_data_queries WHERE id=1;
                   config
---------------------------------------------
 --- !ruby/hash:ActionController::Parameters+
 start_date: 6                              +
 end_date: 0                                +
 interval: day                              +

(1 row)

查看SQL输出,我怀疑它与被序列化为ActionController::Parameters的数据有关。

感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

以下是如何在sql(postgres)中修复它:

UPDATE stored_data_queries SET config = replace(config, 'ActionController::Parameters', 'ActiveSupport::HashWithIndifferentAccess');

答案 1 :(得分:1)

在将Zammad从Rails 4.2升级到Rails 5.0之后也是如此。经过一些研究后,我发现活动记录只是从商店中读取ActiveSupport :: HashWithIndifferentAccess(其他类被跳过)。

因此,对于迁移,您可以在迁移中覆盖ActiveRecord::Store::IndifferentCoder.as_indifferent_hash,从数据库中读取所有相关记录并将其保存回来(然后将所有ActionController :: Parameters转换为ActiveSupport :: HashWithIndifferentAccess)。

对我来说,以下迁移(在Rails 5.0下)已经将所有ActionController :: Parameters转换为ActiveSupport :: HashWithIndifferentAccess:

require 'active_record/store'
module ActiveRecord
  module Store
    class IndifferentCoder
      def self.as_indifferent_hash(obj)
        case obj
        # re-enable using ActionController::Parameters in stores,
        # convert them to ActiveSupport::HashWithIndifferentAccess
        # at reading from db
        when ActionController::Parameters
          obj.permit!.to_h
        # /re-enable
        when ActiveSupport::HashWithIndifferentAccess
          obj
        when Hash
          obj.with_indifferent_access
        else
          ActiveSupport::HashWithIndifferentAccess.new
        end
      end
    end
  end
end

class FixedStoreUpgrade45 < ActiveRecord::Migration[5.0]
  def up
    [Macro, Taskbar, Calendar, Trigger, Channel, Job, PostmasterFilter, Report::Profile, Setting, Sla, Template].each do |class_name|
      class_name.all.each do |record|
        begin
          record.save!
        rescue => e
          Rails.logger.error "Unable to save/update #{class_name}.find(#{record.id}): #{e.message}"
        end
      end
    end
  end
end