as_json不支持参数化方法

时间:2016-08-31 10:39:45

标签: ruby-on-rails json

在' as_json' /' to_json'中传递方法时要创建一个对象的json响应,我们不能在方法中传递参数。是什么原因导致它没有得到支持#as_json / to_json'

例如,

@posts.to_json(
:only => [:title, :body, :created_at, :tags, :category],
:methods => [:likes_count, :comments_count])
}

这里我们不能传递带参数的方法。

1 个答案:

答案 0 :(得分:1)

这不支持开箱即用,但我们可以构建它。
对于Rails 3.2。在config/initializers/full_json.rb中添加此内容。

module ActiveModel
  module Serializers
    module JSON
      def as_full_json(options = nil)
        root = include_root_in_json
        root = options[:root] if options.try(:key?, :root)
        if root
          root = self.class.model_name.element if root == true
          { root => fully_serializable_hash(options) }
        else
          fully_serializable_hash(options)
        end
      end
    end
  end
end

module ActiveModel
  module Serialization
    def fully_serializable_hash(options = nil)
      options ||= {}

      attribute_names = attributes.keys.sort
      if only = options[:only]
        attribute_names &= Array.wrap(only).map(&:to_s)
      elsif except = options[:except]
        attribute_names -= Array.wrap(except).map(&:to_s)
      end

      hash = {}
      attribute_names.each { |n| hash[n] = read_attribute_for_serialization(n) }

      # These two lines do the magic. I check if it's Array, and in case it is, it should accept the arguments.
      method_names = Array.wrap(options[:methods]).select { |n| respond_to?(Array.wrap(n).first) }
      method_names.each { |n| n.is_a?(Array) ? (hash[n.first] = send(*n)) : (hash[n] = send(n)) }

      serializable_add_includes(options) do |association, records, opts|
        hash[association] = if records.is_a?(Enumerable)
                              records.map { |a| a.serializable_hash(opts) }
                            else
                              records.serializable_hash(opts)
                            end
      end

      hash
    end
  end
end

尝试:

# Here method_with_arg is the method which accepts argument. 'arg' is the argument
@posts.as_full_json(
:only => [:title, :body, :created_at, :tags, :category],
:methods => [:likes_count, :comments_count, [:method_with_arg, 'arg']])
}.to_json

我确定可以清除和减少此代码。可能通过使用别名链或其他东西。你可以做得更远。如果这对您有用,请告诉我。

干杯