Closed 23tux closed 3 years ago
Hi @23tux! Yeah, we have a OneOf for that.
Thanks for your answer, didn't know that!
But as far as I can see, you only have access to the json column itself, and not other columns of the record, am I right?
I also wonder how to decide if you want to use to_type
or to_array_type
? In the OneOf Example, only the base class is set inside the block, not the type itself.
and not other columns of the record
Yeah, this is how it works now, and there is a chance that we do not have access to the "parent" model at the moment of deserialization (so we won't be able to refer to other fields).
how to decide if you want to use to_type or to_array_type?
to_type
is used when there is a single JSON (e.g., { color: "red" }
), while to_array_type
wraps array of JSONs (e.g., [{ color: "red" }, { color: "green" }]
)
@DmitryTsepelev thanks, I've managed to inject the type into the json column, so this works.
One last question: Is it possible to use the ActiveRecord::Type::Json
type in StoreModel.one_of
?
I tried to use
OneOfConfigurations = StoreModel.one_of do |json|
json["_model"]&.constantize || ActiveRecord::Type::Json
end
but this throws an error
StoreModel::Types::ExpandWrapperError: ActiveRecord::Type::Json is an invalid model klass
For some models I have to provide a fallback if the underlying data doesn't match the StoreModel, and otherwise ActiveSupport throws a
ActiveModel::UnknownAttributeError: unknown attribute 'foo' for MyModel.
StoreModel::Types::ExpandWrapperError
is thrown when the type that returned from the block does not include a StoreModel::Model
module (code is here). I guess it might be possible to define a custom class including that module that behaves like ActiveRecord::Type::Json
.
unknown attribute 'foo'
Interesting, sounds like JSON stored in database does not have foo field, while it's defined in the StoreModel class, am I right? I'm asking because we do handle the opposite scenario using unknown attributes.
@DmitryTsepelev thanks for the hint to the unknown attributes! That solves indeed my problem, I just provide a generic fallback model.
Is it possible to define the type of a store model based on another field? For example something like this:
I'm not sure if this is even a StoreModel related question, maybe it has more to do with how ActiveModel includes it's attributes.
So far, I have overwritten the getter of
config
to achieve this, but maybe there is a way to do it with build in functionality: