Representable::JSON::Collection does not change json output

126 views
Skip to first unread message

Maximilian Schulz

unread,
Jun 11, 2014, 11:55:53 AM6/11/14
to roar...@googlegroups.com
I have no idea what I am missing, but I must be missing something. My setup is as follows:

# app/representers/api/mandates_representer.rb
module Api
  module MandatesRepresenter
    include Representable::JSON::Collection

    items extend: MandateRepresenter, class: Mandate
  end
end

# app/representers/api/mandate_representer.rb
module Api
  module MandateRepresenter
    include Roar::Representer::JSON

    property :id
    property :reference
  end
end


Using it with a single mandate, it works perfecty:

Mandate.first.extend(Api::MandateRepresenter).to_json
# => "{\"id\":1,\"reference\":"my-ref"}"

But when using it on the collection, it just renders all attributes:

Mandate.all.extend(Api::MandatesRepresenter).to_json
# => "[{\"id\":2,\"reference\":\"0987654321\",\"ip\":null,\"created_at\":\"2014-06-11T13:52:06.841Z\",\"updated_at\":\"2014-06-11T13:52:06.841Z\"}]"

Any ideas what I am missing?

Nick Sutterer

unread,
Jun 11, 2014, 7:01:22 PM6/11/14
to roar...@googlegroups.com
Hey Max,

can you try something like the following?

  [Mandate.last].extend(Api::MandatesRepresenter).to_json

It might be ActiveRecord's magic that gives us trouble.

Nick


--
You received this message because you are subscribed to the Google Groups "Roar" group.
To unsubscribe from this group and stop receiving emails from it, send an email to roar-talk+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Maximilian Schulz

unread,
Jun 12, 2014, 3:30:02 AM6/12/14
to roar...@googlegroups.com

Unfortunately, the same result. I also tried:

Mandate.all.to_a

But still the same. While checking the github issues I came across an issue which looked a bit similar. Perhaps this helps:

Mandate.all.extend(Api::MandatesRepresenter).singleton_class.ancestors
# => [#<Class:#<Mandate::ActiveRecord_Relation:0x00000106983c10>>, Api::MandatesRepresenter, Representable::Hash::Collection, Representable, Representable::Hash, Mandate::ActiveRecord_Relation, ActiveRecord::Delegation::ClassSpecificRelation, ActiveRecord::Relation, ActiveRecord::FinderMethods, ActiveRecord::Calculations, ActiveRecord::SpawnMethods, ActiveRecord::QueryMethods, ActiveRecord::Batches, ActiveRecord::Explain, ActiveRecord::Delegation, Object, ActiveSupport::Dependencies::Loadable, PP::ObjectMixin, JSON::Ext::Generator::GeneratorMethods::Object, Kernel, BasicObject]

By the way, the "old api" is working as expected. Using "respond_with merchant.mandates.to_a, represent_items_with: MandateRepresenter" gives the expected result.

Nick Sutterer

unread,
Jun 12, 2014, 4:36:21 AM6/12/14
to roar...@googlegroups.com
Ok, then please do this

[Mandate.last].extend(Api::MandatesRepresenter).method(:to_json).source_location

To find out where the bloody to_json method comes from. Thanks

Maximilian Schulz

unread,
Jun 12, 2014, 11:08:21 AM6/12/14
to roar...@googlegroups.com
Ok, that seems to be wrong :)

[Mandate.last].extend(Api::MandatesRepresenter).method(:to_json).source_location
# => ["/Users/namxam/.rvm/gems/ruby-2.1.2/gems/activesupport-4.1.0/lib/active_support/core_ext/object/json.rb", 31]
 

Nick Sutterer

unread,
Jun 12, 2014, 6:42:08 PM6/12/14
to roar...@googlegroups.com
Yeah that's what I was expecting, ActiveSupport is polluting your object. Try using Decorator instead.

class MandateRepresenter < Representable::Decorator

and then

MandatesRepresenter.new([Mandate.last]).to_json

Sorry for that but this is not representable's fault ;)


--

Steve V

unread,
Aug 22, 2014, 8:57:23 PM8/22/14
to roar...@googlegroups.com
Is there a way to work around this other than decorators? I have been beating head against my desk for some time thinking I was doing something wrong. If there's no workaround, maybe the representable docs can be updated somewhere to indicate the issue, so at least people don't waste time. 

Nick Sutterer

unread,
Aug 22, 2014, 9:39:47 PM8/22/14
to roar...@googlegroups.com
The problem here is, we don't know when ActiveSupport kills our representer methods. This is really not my fault but Rails' let's-extend-every-object-with-some-arbitrary-methods. I personally never came across this issue, maybe you can isolate the problem in a tiny Rails app and send it to me?

I'd love to go and see if I can fix it! Thanks!!!

Steve Valaitis

unread,
Aug 23, 2014, 12:23:32 PM8/23/14
to roar...@googlegroups.com
I don't blame you at all. I know how invasive ActiveSupport can be. Here's a repo that shows both this issue, and the failure to extend multiple modules. There's a test file in test/models/representers_test.rb


It's a rails 4 project, so I think you should be able to just bundle, and then run rake.

Steve V

unread,
Aug 31, 2014, 12:07:14 PM8/31/14
to roar...@googlegroups.com
Is there a specific method you use to try and track down this stuff? Good places to set breakpoints, and such? I've debugged some stuff like this in AS before, and it wasn't fun.

Nick Sutterer

unread,
Aug 31, 2014, 6:35:31 PM8/31/14
to roar...@googlegroups.com
My method is usually puts and raise and trying not to get too frustrated... 

Sorry I totally missed the example app you made - I'll have a quick look. Thanks for reminding me :)

Nick


Nick Sutterer

unread,
Aug 31, 2014, 7:26:49 PM8/31/14
to roar...@googlegroups.com
I was able to make it work by simply adding this line to your representer:

require 'representable/json/collection'

Now, the question is... WHYYYY?

Nick Sutterer

unread,
Aug 31, 2014, 8:19:18 PM8/31/14
to roar...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages