Rails 4: render string field as JSON / hash - ruby-on-rails

I have a Rails model in which one of the text fields contains a JSON string. While rendering it in views with JSON format (such as through index or show) I want to convert the string to a JSON hash. How can I do this with jbuilder or otherwise?
In general, how to apply a transform on a field by calling some function, before rendering it via jbuilder.
Of course, the naive solution is to build the JSON manually and use render json: my_json_here but I am looking for a better way.

Well a JSON is a string already... Maybe you want to convert it back to an object...
This will transform you string into a hash or array object.
JSON.parse(string)
If you want to make the other way around, transform you hash or array into a JSON string:
{ foo: 'bar' }.to_json # "{\"foo\":\"bar\"}"
EDIT: As you are looking for something more advanced, I recommend using the gem ActiveModelSerializer, where you create serializer objects that can be used to render ActiveModel data into any format, like JSON.

I think you could use "serialization" to do this where all of the conversion from JSON object to string and back is handled by ruby.
apidock

Related

How to unpack/convert a stringified JSON array to normal JSON array

I am building a Rails 5.2 app.
In this app I am sending parameter from my Angular app to the server with a JSON.stringify object that looks like this when it arrives to the server:
"[{\"price\":\"silver\"},{\"price\":\"bronze\"}]"
I want to "unpack" it to look like a real JSON object again (because Stripe, that I will send this too only accept a JSON object:
[{"price":"silver"},{"price":"bronze"}]
If I run JSON.parse it only converts to a Hash which is not what I want.
If you want to operate or manipulate that JSON then you need to parse it to Hash.
JSON is treated as a string in ruby and you cannot operate properly on that so by parsing it to hash you can manipulate it using ruby also you can again change the resulting hash back to JSON string and as far as I've worked with Stripe it will work, so
For parsing JSON to Hash:
hash = JSON.parse(json_string)
For parsing Hash to JSON:
json_string = JSON.generate(hash)
or
json_string = hash.to_json

Adding default field such as timestamp to json when rendering in rails

I am newbie in Ruby on rails and want to config render :json, always adds an extra field such as timestamp or version at the end of json response. Like this
{
//json data
"time_stamp" : 24312512341235
}
I think it might have better way to do that than adding parameter everytime calling render json
Thanks for helping
Just like html, you can have a layout for JSON responses.
Create a file app/views/layouts/application.json.jbuilder
and fill it with this:
json.merge! JSON.parse(yield)
json.time_stamp Time.now.to_i
Note that you need to make sure you always return a JSON Object and not an Array.

Is it possible to run .to_json on a hash but not have it escape previously .to_json'ified strings?

We have a caching layer that stores json output of strings. I'd like to be able to put these strings into an array which I then transform to json via .to_json but it escapes all the previously encoded json. Is there a way to avoid this?
Here's a sample action to explain:
def index
a={name:"jon", email:"jon#domain.com"}.to_json
r={}
r[:users]=[]
r[:users] << a
render json: r.to_json
end
Outputs:
{"users":["{\"name\":\"jon\",\"email\":\"jon#domain.com\"}"]}
But I want:
{"users":["{"name":"jon","email":"jon#domain.com"}"]}
Though I am not showing it here, I'd be open to using ActiveModelSerializer (the 0.8 branch)
Edit
One possibility is doing a JSON.parse but obviously, that's a bit of a performance hit which I'd like to avoid.
You are converting a json object to another json object.. Try replacing
a={name:"jon", email:"jon#domain.com"}.to_json
by
a={name:"jon", email:"jon#domain.com"}

HAML rendering as_json with hash rocket instead of colon

I'm trying to render a ruby hash to a json string in haml. (the ! tells haml not to escape the output)
! { :name => "Paul" }.as_json
I expect this output
{ "name":"Paul" }
but I get a hash rocket instead of a colon
{ "name"=>"Paul" }
How do I make haml or as_json output a colon instead of a hash rocket for the property/value separator?
as_json is essentially a method that allows you to specify how an object is represented in JSON. It doesn't actually go as far as returning a JSON encoded string. to_json is needed for that.
The reason for this is that you might want to decide which fields your model returns when JSON encoded (say, removing the password from the User model), but by using to_json, you no longer have the ability to nest that within another JSON object, as it's become an encoded and escaped string.
to_json will call as_json, and will encode the return value.
Referenced from:
http://jonathanjulian.com/2010/04/rails-to_json-or-as_json/

jRuby hash iteration newbie here

I am very new to rails in general and what I have is a hash being passed as json for one format and now I need to pass it to the view to work with but I have no idea how to iterate over the hash to make it work in the view as I need to do some type of each loop over it. Its a 2 dimensional hash dunno if that means anything or not.
edit
example
{"status":"successful","service_list":[{"service_name":"mySQL","status":"RUNNING","status_message":"No errors reported","host":"1"},{"service_name":"PHP","status":"RUNNING","status_message":"No errors reported","host":"1"},{"service_name":"APache","status":"RUNNING","status_message":"No errors reported","host":"1"},{"service_name":"Jetty","status":"RUNNING","status_message":"No errors reported","host":"1"}]}
This renders fine when I do it as JSON, but using the same thing to render it out in an HTML based view is where I am getting stuck
You have converted a Ruby has to a JSON hash, which is a Javascript format. In Ruby you would access a hash as follows:
hash = {"foo": "bar"}
puts hash["foo"] # This returns "bar"
JSON is similar to Ruby, and can be accessed in the same manner:
var hash = {"foo": "bar"};
alert(hash["foo"]); # This alerts "bar"
If you want to iterate through this collection in Javascript, you can use a for loop:
var data = {"status":"successful","service_list":[{"service_name":"mySQL","status":"RUNNING","status_message":"No errors reported","host":"1"},{"service_name":"PHP","status":"RUNNING","status_message":"No errors reported","host":"1"},{"service_name":"APache","status":"RUNNING","status_message":"No errors reported","host":"1"},{"service_name":"Jetty","status":"RUNNING","status_message":"No errors reported","host":"1"}]};
for(x=0;x<data["service_list"].length;x++) {
alert(data["service_list"][x]["service_name"]); # This returns "mySQL", ...
};
If you are wanting to convert this JSON object to a Ruby has you can call "JSON.parse" with your JSON string as an argument.

Resources