2017-08-03 38 views
0

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

这里的铁轨输出4控制台:

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

和轨道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输出,我怀疑它有som数据被序列化为ActionController::Parameters

感谢您的帮助!

+0

更新:经过几次实验后,我发现rails 5将对象存储为'ActiveSupport :: HashWithIndifferentAccess'。所以现在的问题是,是否有比原始sql更好的方式来转换存储的对象。 –

+0

这里是如何解决它在sql(postgres)'UPDATE stored_data_queries SET config = replace(config,'ActionController :: Parameters','ActiveSupport :: HashWithIndifferentAccess');' –

回答

0

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

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

对于我来说,下面的迁移(下导轨5.0)一直致力于所有的ActionController ::参数转换成的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 
0

这里是如何解决它的SQL(Postgres的):

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