steel
steel

Reputation: 12520

Convert Active Record Object and String Attributes to JSON

I am trying to convert a Rails record into a fully Javascript-traversable JSON object. I can convert the basic record into JSON just fine, and I can convert each individual attribute into JSON just fine. However, I don't have a good way to convert the entire object into a traversable JSON object. Ideally the solution would not involve iterating over each attribute and converting the value to JSON. How can I completely convert my entire record into a JSON format that I can fully traverse in Javascript?

Below are the steps you would need to take to replicate my problem. Thanks in advance.

# database
MySQL, and the column is a Rails text data type.

# seeds.rb
ModelName.create(
  has_hash_value: { one: { two: { three: "content"} } }
)

# console
$ rake db:seed

# controller
@resource = ModelName.first.to_json

# erb view
<div id="data" data-json="<$= @resource %>"></div>

# generated HTML
{"has_hash_value":"{:one=\u003e{:two=\u003e{:three=\u003e\"content\"}}}",

# javascript
window.data = $('#data').data().json

# browser console
> data.has_hash_value
< "{:one=>{:two=>{:three=>"content"}}}"
> data.has_hash_value.one
< undefined

Update

I've tried @resource = JSON.parse(ModelName.first.to_json), but what is returned is a completely untraversable string. The nested hash is formatted better, however.

# controller
@resource = JSON.parse(ModelName.first.to_json)

# generated HTML
data-json="{"has_hash_value"=>"{:one=>{:two=>{:three=>\"content\"}}}"

# browser console
> data.has_hash_value
< undefined

Update 2

When I seed with the data formatted as either a string or as json, and convert to hash then JSON in the controller, the generated HTML and JS response are cleaner, but I still cannot fully traverse.

# seeds.rb
has_hash_value: { one: { two: { three: "content"} } }.to_json

# controller
@resource = TourAnalytic.first.as_json.to_json

# generated HTML
data-json="{"has_hash_value":"{\"one\":{\"two\":{\"three\":\"content\"}}}"

# browser console
> data.has_hash_value
< Object {has_hash_value: "{"one":{"two":{"three":"content"}}}"}
> data.has_hash_value.one
< undefined

Upvotes: 1

Views: 1964

Answers (1)

Chuck Callebs
Chuck Callebs

Reputation: 16431

The problem is the value of has_hash_value. It's a string (wrapped in "s). This is what I did:

your_hash = { has_hash_value: { one: { two: { three: "content"} } }.to_json }
your_hash[:has_hash_value] = JSON.parse(your_hash[:has_hash_value]

Your hash will then have the value:

{:has_hash_value=>{"one"=>{"two"=>{"three"=>"content"}}}}

I strongly suggest moving all of this code to the model and overwriting the #to_json method.

Upvotes: 1

Related Questions