Let us say I have a model Post which belongs to a User. To convert to json, I do something like this
假设我有一个属于用户的模型贴子。要转换成json,我要这样做
@reply.to_json(:include => {:user => {:only => [:email, :id]},
:only => [:title, :id])
However, I want to set some defaults for this so I don't have to specify :only everytime. I am trying to override as_json to accomplish this. When I add as_json in User model, it is called when I do @user.to_json but when user is included in @reply.to_json, my overriden as_json for User is ignored.
但是,我想为它设置一些默认值,这样我就不必每次都指定:only everytime。我正在尝试覆盖as_json来实现这一点。当我在用户模型中添加as_json时,当我使用@user时就会调用它。但当用户包含在@reply中时。to_json,我的overriden as_json用户被忽略。
How do I make this work?
我要怎么做呢?
Thanks
谢谢
5 个解决方案
#1
31
You can do this by overriding serializable_hash
in your model, like so:
可以通过在模型中重写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
This will affect all serializable methods, including serializable_hash
, to_json
, and to_xml
.
这将影响所有可序列化的方法,包括serizable_hash、to_json和to_xml。
#2
3
In the Reply model:
在应答模式:
def as_json(options = {})
super options.merge(:methods => [:user], :only => [:id, :title])
end
And in the User model:
在用户模型中:
def as_json(options = {})
super options.merge(:only => [:id, :email])
end
When the association is included as a method and not an include, it will run the .to_json on it.
当关联作为一个方法而不是include被包含时,它将在其上运行.to_json。
#3
0
You could add another method to ActiveRecord::Base, like self.to_minimal_json(*only_fields) and build your .to_json call there.
您可以向ActiveRecord: Base添加另一个方法,比如self.to_minimal_json(*only_fields),并在那里构建.to_json调用。
unspectacular, but may work.
不引人注目的,但是可能的工作。
#4
0
So I found out that the problem is that for includes, instead of calling as_json to generate the json, Rails directly calls serializable_hash. Monkey patching fixes the problem. Put this in an initializer
所以我发现问题是for include直接调用serializable_hash而不是调用as_json来生成json。猴子补丁解决了问题。把这个放到初始化器中
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
Notice how the serializable_hash call is replaced with as_json (with an extra parameter to supress addition of root in includes). Now if you has as_json in your model, it will be called even in case of includes
注意,如何用as_json替换serializable_hash调用(在include中添加根的附加参数)。现在,如果您的模型中有as_json,那么即使包含也会调用它
#5
0
As options might under circumstances be nil, we'd better be aware of it:
由于在这种情况下选择可能是零,我们最好知道:
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
#1
31
You can do this by overriding serializable_hash
in your model, like so:
可以通过在模型中重写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
This will affect all serializable methods, including serializable_hash
, to_json
, and to_xml
.
这将影响所有可序列化的方法,包括serizable_hash、to_json和to_xml。
#2
3
In the Reply model:
在应答模式:
def as_json(options = {})
super options.merge(:methods => [:user], :only => [:id, :title])
end
And in the User model:
在用户模型中:
def as_json(options = {})
super options.merge(:only => [:id, :email])
end
When the association is included as a method and not an include, it will run the .to_json on it.
当关联作为一个方法而不是include被包含时,它将在其上运行.to_json。
#3
0
You could add another method to ActiveRecord::Base, like self.to_minimal_json(*only_fields) and build your .to_json call there.
您可以向ActiveRecord: Base添加另一个方法,比如self.to_minimal_json(*only_fields),并在那里构建.to_json调用。
unspectacular, but may work.
不引人注目的,但是可能的工作。
#4
0
So I found out that the problem is that for includes, instead of calling as_json to generate the json, Rails directly calls serializable_hash. Monkey patching fixes the problem. Put this in an initializer
所以我发现问题是for include直接调用serializable_hash而不是调用as_json来生成json。猴子补丁解决了问题。把这个放到初始化器中
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
Notice how the serializable_hash call is replaced with as_json (with an extra parameter to supress addition of root in includes). Now if you has as_json in your model, it will be called even in case of includes
注意,如何用as_json替换serializable_hash调用(在include中添加根的附加参数)。现在,如果您的模型中有as_json,那么即使包含也会调用它
#5
0
As options might under circumstances be nil, we'd better be aware of it:
由于在这种情况下选择可能是零,我们最好知道:
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