Introducing JSON
JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate. JSON is a text format that is completely language independent but uses conventions that are familiar to programmers. These properties make JSON an ideal data-interchange language.
JSON is built on two structures:
- A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.
- An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence.
These are universal data structures. Virtually all modern programming languages support them in one form or another. It makes sense that a data format that is interchangable with programming languages also be based on these structures.
In JSON, they take on these forms:
An object is an unordered set of name/value pairs. An object begins with { (left brace) and ends with } (right brace). Each name is followed by : (colon) and the name/value pairs are separated by , (comma).

An array is an ordered collection of values. An array begins with [ (left bracket) and ends with ] (right bracket). Values are separated by , (comma).

A value can be a string in double quotes, or a number, or true or false or null, or an object or an array. These structures can be nested.

A string is a collection of zero or more Unicode characters, wrapped in double quotes, using backslash escapes. A character is represented as a single character string. A string is very much like a C or Java string.

A number is very much like a C or Java number, except that the octal and hexadecimal formats are not used.

JSON in JavaScript
JSON is a subset of the object literal notation of JavaScript. Since JSON is a subset of JavaScript, it can be used in the language with no muss or fuss.
var myJSONObject = {"bindings": [ {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"}, {"ircEvent": "PRIVMSG", "method": "deleteURI", "regex": "^delete.*"}, {"ircEvent": "PRIVMSG", "method": "randomURI", "regex": "^random.*"} ]};
In this example, an object is created containing a single member "bindings", which contains an array containing three objects, each containing "ircEvent", "method", and "regex" members.
Members can be retrieved using dot or subscript operators.
myJSONObject.bindings[0].method // "newURI"
To convert a JSON text into an object, use the eval() function. eval() invokes the JavaScript compiler. Since JSON is a proper subset of JavaScript, the compiler will correctly parse the text and produce an object structure.
var myObject = eval('(' + myJSONtext + ')');
The eval function is very fast. However, it can compile and execute any JavaScript program, so there can be security issues. The use of eval is indicated when the source is trusted. This is commonly the case in web applications when a web server is providing both the base page and the JSON data. There are cases where the source is not trusted. In particular, clients should never be trusted.
When security is a concern it is better to use a JSON parser. A JSON parser will only recognize JSON text and so is much safer:
var myObject = myJSONtext.parseJSON(filter);
The optional filter parameter is a function which will be called for every key and value at every level of the final result. Each value will be replaced by the result of the filter function. This can be used to reform generic objects into instances of classes, or to transform date strings into Date objects.
myData = text.parseJSON(function (key, value) { return key.indexOf('date') >= 0 ? new Date(value) : value; });
A JSON stringifier goes in the opposite direction, converting JavaScript data structures into JSON text. JSON does not support cyclic data structures, so be careful to not give cyclical structures to the JSON stringifier.
var myJSONText = myObject.toJSONString();
The toJSONString method can take an optional array of strings. These strings are used to select the properties that will be included in the JSON text. Otherwise, all of the properties of the object (excluding the prototype chain) will be included. In any case, values that do not have a representation in JSON (such as functions, undefined, and host objects) are excluded.
The open source code of a JSON parser and JSON stringifier is available at http://www.json.org/json.js.
JSON in Ruby
To use JSON you have to install it.
gem install json
To use JSON
require 'json'
To create a JSON text from a ruby data structure, you can call JSON.generate (or JSON.unparse) like that:
json = JSON.generate [1, 2, {"a"=>3.141}, false, true, nil, 4..10]
# => "[1,2,{\"a\":3.141},false,true,null,\"4..10\"]"
It‘s also possible to call the to_json method directly.
json = [1, 2, {"a"=>3.141}, false, true, nil, 4..10].to_json
# => "[1,2,{\"a\":3.141},false,true,null,\"4..10\"]"
To create a valid JSON text you have to make sure, that the output is embedded in either a JSON array [] or a JSON object {}. The easiest way to do this, is by putting your values in a Ruby Array or Hash instance.
To get back a ruby data structure from a JSON text, you have to call JSON.parse on it:
JSON.parse json
# => [1, 2, {"a"=>3.141}, false, true, nil, "4..10"]
Note, that the range from the original data structure is a simple string now. The reason for this is, that JSON doesn‘t support ranges or arbitrary classes. In this case the json library falls back to call Object#to_json, which is the same as to_s.to_json.
It‘s possible to extend JSON to support serialization of arbitrary classes by simply implementing a more specialized version of the to_json method, that should return a JSON object (a hash converted to JSON with to_json) like this
class Range
def to_json(*a)
{
'json_class' => self.class.name, # = 'Range'
'data' => [ first, last, exclude_end? ]
}.to_json(*a)
end
end
The hash key ‘json_class’ is the class, that will be asked to deserialize the JSON representation later. In this case it‘s ‘Range’, but any namespace of the form ‘A::B’ or ’::A::B’ will do. All other keys are arbitrary and can be used to store the necessary data to configure the object to be deserialized.
If a the key ‘json_class’ is found in a JSON object, the JSON parser checks if the given class responds to the json_create class method. If so, it is called with the JSON object converted to a Ruby hash. So a range can be deserialized by implementing Range.json_create like this:
class Range
def self.json_create(o)
new(*o['data'])
end
end
Now it possible to serialize/deserialize ranges as well:
json = JSON.generate [1, 2, {"a"=>3.141}, false, true, nil, 4..10]
# => "[1,2,{\"a\":3.141},false,true,null,{\"json_class\":\"Range\",\"data\":[4,10,false]}]"
JSON.parse json
# => [1, 2, {"a"=>3.141}, false, true, nil, 4..10]
JSON.generate always creates the shortest possible string representation of a ruby data structure in one line. This good for data storage or network protocols, but not so good for humans to read. Fortunately there‘s also JSON.pretty_generate (or JSON.pretty_generate) that creates a more readable output:
puts JSON.pretty_generate([1, 2, {"a"=>3.141}, false, true, nil, 4..10])
[
1,
2,
{
"a": 3.141
},
false,
true,
null,
{
"json_class": "Range",
"data": [
4,
10,
false
]
}
]
ActiveRecords to JSON
Put following code in lib/active_record/json.rb
require 'json'
module ActiveRecord
module Json # :nodoc:
DEFAULT_CONVERSIONS = { Time => [:to_s, :db] }
def to_json(conversions = {})
conversions = DEFAULT_CONVERSIONS.merge(conversions)
self.attributes.keys.inject({}) do hsh, key
value = self.send(key)
hsh.merge(key => conversions[value.class] ? value.send(*conversions[value.class]) : value.to_s)
end.to_json
end
end
end
Put following code at the end in environment.rb. This is to make to_json method automatically available to all the models on the start of the server.
require "#{RAILS_ROOT}/lib/active_record/json"
ActiveRecord::Base.class_eval { include ActiveRecord::Json }
Following is a working example.
Create table using following sql.
CREATE TABLE `advertisements` ( `id` int(16) NOT NULL auto_increment, `title` varchar(64) NOT NULL, `ad_type` int(16) NOT NULL, `display_text` varchar(64) default NULL, `display_other` blob, `image_path` varchar(256) default NULL, `start_date` date NOT NULL, `end_date` date NOT NULL, `provider_id` int(16) NOT NULL, `provider_name` varchar(128) default NULL, `user_id` int(16) NOT NULL, `user_name` varchar(64) default NULL, `modified_at` datetime NOT NULL, `created_at` datetime NOT NULL, PRIMARY KEY (`id`))
In the model
class Advertisement < ActiveRecord::Base
end
In the controller
class JsonController < ApplicationController
def obj_to_json
begin
@add=Advertisement.find(1)
render :json=>@add.to_json
rescue Exception=>e
puts e
end
end
def json_to_obj
begin
j=JSON.parse params[:json_obj]
@add=Advertisement.new j
puts @add.start_date
render :text=>'success'
rescue Exception=>e
puts e
end
end
def index
end
end
In the rhtml
Reference:
http://www.json.org/
http://snippets.dzone.com/posts/show/474