Sha256: db1395bad1e9584bb56b21f9640ec0a198cdfc6aec815c929a63e665226f0449

Contents?: true

Size: 1.33 KB

Versions: 6

Compression:

Stored size: 1.33 KB

Contents

# frozen_string_literal: true

require "active_model"

module StoreModel
  module Types
    class ArrayType < ActiveModel::Type::Value
      def initialize(model_klass)
        @model_klass = model_klass
      end

      def type
        :array
      end

      def cast_value(value)
        case value
        when String then decode_and_initialize(value)
        when Array then ensure_model_class(value)
        when nil then value
        else
          raise StoreModel::Types::CastError,
                "failed casting #{value.inspect}, only String or Array instances are allowed"
        end
      end

      def serialize(value)
        case value
        when Array
          ActiveSupport::JSON.encode(value)
        else
          super
        end
      end

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

      private

      # rubocop:disable Style/RescueModifier
      def decode_and_initialize(array_value)
        decoded = ActiveSupport::JSON.decode(array_value) rescue []
        decoded.map { |attributes| @model_klass.new(attributes) }
      end
      # rubocop:enable Style/RescueModifier

      def ensure_model_class(array)
        array.map do |object|
          object.is_a?(@model_klass) ? object : @model_klass.new(object)
        end
      end
    end
  end
end

Version data entries

6 entries across 6 versions & 1 rubygems

Version Path
store_model-0.5.1 lib/store_model/types/array_type.rb
store_model-0.5.0 lib/store_model/types/array_type.rb
store_model-0.4.1 lib/store_model/types/array_type.rb
store_model-0.4.0 lib/store_model/types/array_type.rb
store_model-0.3.2 lib/store_model/types/array_type.rb
store_model-0.3.1 lib/store_model/types/array_type.rb