2016-08-31 14 views
3

'as_json'/'to_json'にメソッドを渡してオブジェクトのjsonレスポンスを作成する際に、メソッド内でパラメータを渡すことはできません。何その背後にある理由は、「as_json/to_jsonを」でサポートされていないas_jsonはパラメータ化されたメソッドをサポートしません

例えば、ここで

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

我々は、引数を持つメソッドを渡すことはできません。

答えて

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 

私はこのコードを清掃して少なくすることができると確信しています。エイリアスチェーンなどを使用している可能性があります。あなたはそれをさらに行うことができます。これがあなたのために働くかどうか私に教えてください。

乾杯

+0

ありがとう、私はこの実装を試してみると、これは私のために動作する場合はお知らせします。しかし、この機能が含まれていないことがわかっている特定の理由はありますか? –

+0

私はJSONに変換するAPIと同じように、すでに多くのオプションと複雑さがあると思います。私はこれがdevsの間のより混乱を防ぐために追加されていないと思う。 – kiddorails

+0

これを含めるために問題を提起する必要があると思いますか?これについては非常に多くの回避策が見られました。これが含まれていればよい考えではないでしょうか? –

関連する問題