Recently I was working on a rails app where its datasource was a API instead of a database. My team wants all the components to be seperate, thats the reason we go with this kind of architecture. We were using Rails 3.2 and ActiveResource for the frontend and of course our API is build with rails-api.
Here is my sample data from the JSON API.
ActiveResource will deal with the data pretty well except contacts
. It tends to create an object for contacts. The ActiveResource object will be something similar to
#<Store:0xb4aaec4 @attributes={ “store” => { “description” => “some description”, “contacts” => #<Store::Contact:0xb4aa884 @attributes={ “contact” => {“opening_time” => “09:00”, “clo sing_time” =>”18:00”,”holidays”=>[“Sunday”], “message” =>”” } },@prefix_options={}, @persisted=false>, “name”=> “some store” } } , @prefix_options={}, @persisted=false>
So I hope you have noticed that contacts is an object of Store::Contact
. This is pretty handy anyway but the main issue was contacts
attributes are are enclosed inside a root element contact
. This is not an issue if you are just finding and displaying data. But its a real issue when you try to create or update.
If we continue the same structure and use Store.create
it will create the record like
Since we are using MongoDB to store data, the whole store and contact is a single document, the un-nessassory nesting for contacts was the real problem for us. So we thought of diveing into ActiveResource source code to get a solution. Atlast we had two ways to solve this issue.
- Create a model for
Store::Contact
withself.include_root_in_json = false
- Monkey patch
ActiveResource::Base.create_resource_for
method
1. Create a model
This will work out perfectly only if you have one or two situations like Store::Contact
or else you need to create a model for every attributes holding a hash value.
It will be better to create the model in the parent model file itself so that it will load the class when ever the parent model loads.
Now when ever the we call Store.create
ActiveResource strip the extra nesting of contacts.
2. Monkey patch ActiveResource
If you are new to monkey patching, you can take a look to my another blog post which explains how monkey patch in rails.
My patch for this problem look like,
This will work perfectly if you want all your sub models to strip the root element.
Since we had a lot of attributes holding hash value in different models we planned to move with the second option and so far it works pretty fine.