Ruby on rails Rails中to_json的默认值为:include

Ruby on rails Rails中to_json的默认值为:include,ruby-on-rails,json,Ruby On Rails,Json,假设我有一个属于用户的模型帖子。为了转换为json,我做了如下操作 @reply.to_json(:include => {:user => {:only => [:email, :id]}, :only => [:title, :id]) 但是,我想为此设置一些默认值,这样就不必指定:仅限每次。我正试图重写as_json以实现这一点。当我在用户模型中添加as_json时,当我执行@User.to_json时会调用它,但当@reply.t

假设我有一个属于用户的模型帖子。为了转换为json,我做了如下操作

@reply.to_json(:include => {:user => {:only => [:email, :id]}, 
               :only => [:title, :id])
但是,我想为此设置一些默认值,这样就不必指定:仅限每次。我正试图重写as_json以实现这一点。当我在用户模型中添加as_json时,当我执行@User.to_json时会调用它,但当@reply.to_json中包含用户时,会忽略我对User的重写as_json

我该怎么做


谢谢

您可以向ActiveRecord::Base添加另一个方法,比如self.to\u minimal\u json(*仅\u字段),并在那里构建.to\u json调用


不引人注目,但可能会起作用。

因此我发现问题在于,对于include,Rails直接调用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

请注意,可序列化的_散列调用如何被替换为as_json(使用一个额外的参数来禁止在includes中添加root)。现在,如果您的模型中有as_json,那么即使在包含的情况下也会调用它,因为在某些情况下选项可能为零,我们最好注意:

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
在答复模型中:

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。

您可以通过覆盖模型中的
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
类回复{:user=>{:only=>[:email,:id]},
:only=>[:title,:id]
}.更新(选项)
超级(选项)
结束
结束

这将影响所有可序列化方法,包括
serializable_hash
to_json
,以及
to_xml

谢谢。在进一步研究中,我遇到了这个gem,它解决了我开始解决的原始问题-(这是对下面答案的一个更改,出于未知原因,它显示在上面,抱歉)这是可行的,但我更喜欢覆盖可序列化的_散列,这也会影响到_xml。