Rails3中的JSON

原创文章,转载请注明来源并保留原文链接

Rails 3.2.12

to_json

#to_json是由gem ‘json’引入的,但是ActiveSupport重写了,和as_json联系起来

[Object, Array, FalseClass, Float,
 Hash, Integer, NilClass, String, TrueClass].each do |klass|
  klass.class_eval do
    def to_json(options = nil)
      ActiveSupport::JSON.encode(self, options)
    end
  end
end

ActiveSupport::JSON#encode

def encode(value, use_options = true)
  check_for_circular_references(value) do
    jsonified = use_options ? value.as_json(options_for(value)) : value.as_json
    jsonified.encode_json(self)
  end
end

#as_json

这个直接看api就知道了,http://api.rubyonrails.org/classes/ActiveModel/Serializers/JSON.html

render :json => @xxx

来看看render :json是如何实现的:

actionpack/lib/action_controller/metal/renderers

add :json do |json, options|
  json = json.to_json(options) unless json.kind_of?(String)
  json = "#{options[:callback]}(#{json})" unless options[:callback].blank?
  self.content_type ||= Mime::JSON
  json
end

可以看到就是调用了to_json,如果是String就直接返回,如果有callback就返回jsonp的格式

另外我们可以添加新的`renderer`:

ActionController::Renderers.add :csv do |obj, options|
  filename = options[:filename] || 'data'
  str = obj.respond_to?(:to_csv) ? obj.to_csv : obj.to_s
  send_data str, :type => Mime::CSV,
   :disposition => "attachment; filename=#{filename}.csv"
end

# 使用

render :csv => @csvable, :filename => @csvable.name

总结:尽量不要在rails3中重写to_json,如果确实需要自己构造json,重写as_json方法。

One thought on “Rails3中的JSON

  1. Pingback: 改善Rails3中render json的性能 | Zires

Leave a Reply

Your email address will not be published. Required fields are marked *