representable icon indicating copy to clipboard operation
representable copied to clipboard

No way to error on unknown properties

Open imoverclocked opened this issue 8 years ago • 5 comments

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.

imoverclocked avatar Jun 28 '17 01:06 imoverclocked

[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

imoverclocked avatar Jun 28 '17 01:06 imoverclocked

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.

apotonick avatar Jun 28 '17 01:06 apotonick

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:

apotonick avatar Jun 28 '17 01:06 apotonick

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.

imoverclocked avatar Jun 28 '17 03:06 imoverclocked

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.

apotonick avatar Jun 28 '17 04:06 apotonick