让我们说我有一个属于用户的模型帖子。要转换为json,我会做这样的事情
@reply.to_json(:include => {:user => {:only => [:email, :id]},
:only => [:title, :id])
但是,我想为此设置一些默认值,所以我不必每次都指定:我试图覆盖as_json来实现这一目标。当我在User模型中添加as_json时,在我执行@ user.to_json时会调用它,但是当用户包含在@ reply.to_json中时,我的覆盖用户as_json将被忽略。
如何使这项工作?
由于
答案 0 :(得分:33)
您可以通过覆盖模型中的serializable_hash
来执行此操作,如下所示:
class Reply < ActiveRecord::Base
def serializable_hash(options={})
options = {
:include => {:user => {:only => [:email, :id]},
:only => [:title, :id]
}.update(options)
super(options)
end
end
这会影响所有可序列化的方法,包括serializable_hash
,to_json
和to_xml
。
答案 1 :(得分:3)
在回复模型中:
def as_json(options = {})
super options.merge(:methods => [:user], :only => [:id, :title])
end
在用户模型中:
def as_json(options = {})
super options.merge(:only => [:id, :email])
end
当关联作为方法而不是include包含时,它将在其上运行.to_json。
答案 2 :(得分:0)
您可以向ActiveRecord :: Base添加另一个方法,例如self.to_minimal_json(* only_fields),并在那里构建您的.to_json调用。
不引人注目,但可能会奏效。
答案 3 :(得分:0)
所以我发现问题是对于includes,而不是调用as_json来生成json,Rails直接调用serializable_hash。猴子修补修复了这个问题。把它放在初始化器
中module ActiveRecord #:nodoc:
module Serialization
def serializable_hash(options = nil)
options = options.try(:clone) || {}
options[:except] = Array.wrap(options[:except]).map { |n| n.to_s }
options[:except] |= Array.wrap(self.class.inheritance_column)
hash = super(options)
#serializable_add_includes(options) do |association, records, opts|
#hash[association] = records.is_a?(Enumerable) ?
#records.map { |r| r.serializable_hash(opts) } :
#records.serializable_hash(opts)
#end
serializable_add_includes(options) do |association, records, opts|
hash[association] = records.is_a?(Enumerable) ?
records.map { |r| r.as_json(opts.merge(:no_root => true)) } :
records.as_json(opts.merge(:no_root => true))
end
hash
end
end
end
module ActiveModel
# == Active Model JSON Serializer
module Serializers
module JSON
def as_json(options = nil)
hash = serializable_hash(options)
if include_root_in_json and !options[:no_root]
custom_root = options && options[:root]
hash = { custom_root || self.class.model_name.element => hash }
end
hash
end
end
end
end
注意serializable_hash调用是如何用as_json替换的(带有一个额外的参数来抑制在include中添加root)。现在,如果您的模型中有as_json,即使包含
,也会调用它答案 4 :(得分:0)
由于选项在某些情况下可能为零,我们最好注意一下:
module ActiveModel
# == Active Model JSON Serializer
module Serializers
module JSON
def as_json(options)
options ||= {}
hash = serializable_hash(options)
if include_root_in_json and !options[:no_root]
custom_root = options && options[:root]
hash = { custom_root || self.class.model_name.element => hash }
end
hash
end
end
end
end