如何在数组中使用自定义类型

时间:2019-07-31 15:34:19

标签: ruby-on-rails

在Rails 6应用中,我试图使用自定义类型来序列化/反序列化JSONB数组

这是我的代码

class CreateAnalyses < ActiveRecord::Migration[6.0]
  def change
    create_table :analyses do |t|
      t.string  :name,           null: false
      t.jsonb   :resources,      null: false, default: []
      t.timestamps
    end
  end
end


class Analysis  < ApplicationRecord
  attribute :resources, ResourceType.new
end


class ResourceType < ActiveModel::Type::Value
  def cast(json_string)
    attribute_hash = JSON.parse(json_string, symbolize_names: true)

    attribute_hash.each_with_object([]) do |attributes, collection|
      collection << Resource.new(attributes)
    end
  end

  def serialize(resources)
    resources.map { |r| r.to_hash.to_json }
  end
end


class Resource
  attr_accessor :from, :to

  def initialize(attributes = {})
    self.from = attributes[:from]
    self.to = attributes[:to]
  end

  def to_hash()
    {
      from: self.from,
      to: self.to
    }
  end
end

获取分析时,资源将正确投放:

<Analysis id: 1, name: "monthly", resources: [#<Resource:0x00007fd60adf05d8 @from=0, @to=10>, #<Resource:0x00007fd60adf05b0 @from=0, @to=10>], created_at: "2019-07-31 14:06:09", updated_at: "2019-07-31 14:06:09">

但是,当我添加资源并尝试将其保存回数据库时,记录既不会更新,也不会引发错误。

我在这里错过了什么吗?

1 个答案:

答案 0 :(得分:0)

我认为问题是 rails 不知道属性改变了,所以它没有触发 dB 事务。

尝试将以下方法添加到您的类型中:

def changed_in_place?(raw_old_value, new_value)
  raw_old_value != serialize(new_value)
end