Class: ActiveJsonModel::ActiveRecordType
- Inherits:
-
ActiveRecord::Type::Value
- Object
- ActiveRecord::Type::Value
- ActiveJsonModel::ActiveRecordType
- Includes:
- ActiveModel::Type::Helpers::Mutable
- Defined in:
- lib/active_json_model/active_record_type.rb
Overview
Allows instances of ActiveJsonModels to be serialized JSONB columns for ActiveRecord models.
class Credentials < ::ActiveJsonModel
def self.attribute_type
ActiveRecordType.new(Credentials)
end
end
class User < ActiveRecord::Base
attribute :credentials, Credentials.attribute_type
end
Alternatively, the type can be registered ahead of time:
# config/initializers/types.rb
ActiveRecord::Type.register(:credentials_type, Credentials.attribute_type)
Then the custom type can be used as:
class User < ActiveRecord::Base
attribute :credentials, :credentials_type
end
This is based on: jetrockets.pro/blog/rails-5-attributes-api-value-objects-and-jsonb
Direct Known Subclasses
Instance Method Summary collapse
- #cast(value) ⇒ Object
-
#changed_in_place?(raw_old_value, new_value) ⇒ Boolean
Override to handle issues comparing hashes encoded as strings, where the actual order doesn’t matter.
- #deserialize(value) ⇒ Object
-
#initialize(clazz) ⇒ ActiveRecordType
constructor
Create an instance bound to a ActiveJsonModel class.
- #serialize(value) ⇒ Object
- #type ⇒ Object
Constructor Details
#initialize(clazz) ⇒ ActiveRecordType
Create an instance bound to a ActiveJsonModel class.
e.g.
class Credentials < ::ActiveJsonModel; end
#...
return ActiveRecordType.new(Credentials)
44 45 46 |
# File 'lib/active_json_model/active_record_type.rb', line 44 def initialize(clazz) @clazz = clazz end |
Instance Method Details
#cast(value) ⇒ Object
52 53 54 |
# File 'lib/active_json_model/active_record_type.rb', line 52 def cast(value) @clazz.active_json_model_cast(value) end |
#changed_in_place?(raw_old_value, new_value) ⇒ Boolean
Override to handle issues comparing hashes encoded as strings, where the actual order doesn’t matter.
76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/active_json_model/active_record_type.rb', line 76 def changed_in_place?(raw_old_value, new_value) if raw_old_value.nil? || new_value.nil? raw_old_value == new_value else # Decode is necessary because postgres can change the order of hashes. Round-tripping on the new value side # is to handle any dates that might be rendered as strings. decoded_raw = ::ActiveSupport::JSON.decode(raw_old_value) round_tripped_new = ::ActiveSupport::JSON.decode(new_value.class.dump(new_value)) decoded_raw != round_tripped_new end end |
#deserialize(value) ⇒ Object
56 57 58 59 60 61 62 63 |
# File 'lib/active_json_model/active_record_type.rb', line 56 def deserialize(value) if String === value decoded = ::ActiveSupport::JSON.decode(value) rescue nil @clazz.load(decoded) else super end end |
#serialize(value) ⇒ Object
65 66 67 68 69 70 71 72 73 |
# File 'lib/active_json_model/active_record_type.rb', line 65 def serialize(value) if value.respond_to?(:dump_to_json) ::ActiveSupport::JSON.encode(value.dump_to_json) elsif ::Hash === value || ::HashWithIndifferentAccess === value || ::Array === value ::ActiveSupport::JSON.encode(value) else super end end |
#type ⇒ Object
48 49 50 |
# File 'lib/active_json_model/active_record_type.rb', line 48 def type :jsonb end |