No way to error on unknown properties
Given a class:
class SongRepresenter < Representable::Decorator
include Representable::JSON
property :title
property :track
end
and some data to instantiate it with:
{"title": "Foggy Mountain Breakdown", "track": 2, "genre": "bluegrass"}
There is no way to discover that genre is about to be harshly ignored or dropped on the ground. Another similar problem with slightly different data:
{"title": "Foggy Mountain Breakdown", "trach": 2}
since trach != track, our optional attribute is also silently dropped without warning.
[4] pry(main)> class Song
[4] pry(main)* attr_accessor :title
[4] pry(main)* attr_accessor :track
[4] pry(main)* attr_accessor :foo
[4] pry(main)* end
=> nil
[5] pry(main)> puts SongRepresenter.new(Song.new()).from_json(%{ {"title":"Roxanne", "foo": "bar", "baz": "quux"} }).to_json
{"title":"Roxanne"}
=> nil
Yes, that's per design! Representable is a document mapper and not a form object.
We're actually thinking about allowing the detection of that, since it will also be very helpful in Reform.
The problem is that this might appear very simple with hashes (as in, find all keys in the incoming doc, compare to what we have), however, with XML documents as an example, this gets much trickier. I am wondering if that should probably be some Reform-specific feature, instead. :thinking:
Yeah, I was browsing through the source to see if there would be any quick+clean way to patch this in but nothing popped out at me. The current design feels pretty heavy towards not having this feature.
Some extremely pragmatic part of me is tempted to just serialize/unserialize and compare the result to see if everything is accounted for. The rest of me is beating the pragmatic part of me down and hoping for a better solution.
I understand - and I recommend you to check out how we handle that in Trailblazer or directly in Reform, where the form object applies a deserializing representer to itself. The representer per design has no knowledge about validations of any kind, but just parses values it knows to the form. The form then says "that's fine" or marks errors.
You can also override from_hash in every Representer and do the check there. The list of properties can be retrieved via Representer::definitions.