Prevent mapping of nested attributes to Models #91

Closed
bwiggs opened this Issue Aug 22, 2013 · 5 comments

Comments

Projects
None yet
4 participants

bwiggs commented Aug 22, 2013

Is there any way to prevent ActiveResource from mapping nested attributes in an API response to Models within my application?

ex:

API Response

{

    "eventDate": "2012-09-29T23:00:00.000Z",
    "eventState": "final",
    "sport": {
        "sportName": "Football",
        "sportCode": "m-footbl"
    },
    "type": "SportsEvent",
    "uid": "stats-event-1180289",
}

I have a model called Sport, which seems to be getting mapped to that particular property. I'd like to prevent that from happening, possible?

Contributor

MorganShowman commented Aug 23, 2013

Is your Active Resource class in the same namespace as the sport model?

bwiggs commented Aug 23, 2013

Yes it is.

app/models/SportEvent.rb

class SportEvent < ActiveResource::Base
  self.site = 'http://example.com/api/'
  self.element_name = 'events'
end

app/models/Sport.rb

class Sport < ActiveRecord::Base
  #...
end
Contributor

MorganShowman commented Aug 25, 2013

When ActiveResource loads a value that is a hash it looks for a class of the same name to use. If it doesn't find the class, Active Resource creates a new class to use. In your example you have:

"sport": {
  "sportName": "Football",
  "sportCode": "m-footbl"
}

When sport is loaded, the class Sport is found and used. To avoid this you can use different class/key names or put your classes Sport and SportEvent into different namespaces.

I'm not sure which way is best for your situation but I might suggest putting your Active Resource model(s) in it's/their own namespace like this:

class Sport
  # ...
end

module Api
  class SportEvent
    # ...
  end
end
# or
class Api::SportEvent
  # ...
end

This should solve the problem and what you name the namespace is entirely up to you, I just used Api for lack of a better name.

Owner

jeremy commented Sep 25, 2014

@jeremy jeremy closed this Sep 25, 2014

ArtieReus commented Aug 31, 2016

I found out another way to prevent this recursive creation of model objects in attributes hashes. You could add a class as following for each attribute you want to prevent nested object creation in your model class.

Lets say you want that the attribute tags, which is a hash, to be ignored in your model. Add a class with the attribute name and override the initializer. It will assign directly the content to the attributes variable.

class OriginalModel < ActiveResource::Base

    class Tags < ActiveResource::Base
      def initialize(attributes = {}, persisted = false)
        @attributes     = attributes.with_indifferent_access
        @prefix_options = {}
        @persisted = persisted
      end
    end

end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment