シリアライザーを持っています
class FundingSerializer < ActiveModel::Serializer
attributes :id,
has_one :user
has_one :tournament
embed :ids, include: true
end
適切な関連付けで初期化されます
FundingSerializer.new(Funding.first).to_json
利回り
"{\"users\":[{\"id\":2,\"first_name\":\"Nick\"}],\"tournaments\":[{\"id\":1,\"end_date\":\"2013-07-21T23:18:54.981Z\",\"start_date\":\"2013-07-14T23:18:54.980Z\"}],\"funding\":{\"id\":1}}"
しかし、
FundingSerializer.new(Funding.all).to_json
このエラーを取得します。
undefined method `read_attribute_for_serialization' for #<ActiveRecord::Relation::ActiveRecord_Relation_Funding:0x007f998910a250>
from /Users/nicholasshook/.rvm/gems/Ruby-2.0.0-p247@pokerfund/gems/activerecord-4.0.0/lib/active_record/relation/delegation.rb:121:in `method_missing'
from /Users/nicholasshook/.rvm/gems/Ruby-2.0.0-p247@pokerfund/gems/activerecord-4.0.0/lib/active_record/relation/delegation.rb:68:in `method_missing'
from /Users/nicholasshook/.rvm/gems/Ruby-2.0.0-p247@pokerfund/gems/active_model_serializers-0.8.1/lib/active_model/serializer.rb:99:in `block in attribute'
from (eval):3:in `_fast_attributes'
from /Users/nicholasshook/.rvm/gems/Ruby-2.0.0-p247@pokerfund/gems/active_model_serializers-0.8.1/lib/active_model/serializer.rb:466:in `rescue in attributes'
from /Users/nicholasshook/.rvm/gems/Ruby-2.0.0-p247@pokerfund/gems/active_model_serializers-0.8.1/lib/active_model/serializer.rb:454:in `attributes'
from /Users/nicholasshook/.rvm/gems/Ruby-2.0.0-p247@pokerfund/gems/active_model_serializers-0.8.1/lib/active_model/serializer.rb:478:in `_serializable_hash'
from /Users/nicholasshook/.rvm/gems/Ruby-2.0.0-p247@pokerfund/gems/active_model_serializers-0.8.1/lib/active_model/serializer.rb:360:in `serializable_hash'
from /Users/nicholasshook/.rvm/gems/Ruby-2.0.0-p247@pokerfund/gems/active_model_serializers-0.8.1/lib/active_model/serializer.rb:344:in `as_json'
from /Users/nicholasshook/.rvm/gems/Ruby-2.0.0-p247@pokerfund/gems/activesupport-4.0.0/lib/active_support/json/encoding.rb:50:in `block in encode'
from /Users/nicholasshook/.rvm/gems/Ruby-2.0.0-p247@pokerfund/gems/activesupport-4.0.0/lib/active_support/json/encoding.rb:81:in `check_for_circular_references'
from /Users/nicholasshook/.rvm/gems/Ruby-2.0.0-p247@pokerfund/gems/activesupport-4.0.0/lib/active_support/json/encoding.rb:49:in `encode'
from /Users/nicholasshook/.rvm/gems/Ruby-2.0.0-p247@pokerfund/gems/activesupport-4.0.0/lib/active_support/json/encoding.rb:34:in `encode'
from /Users/nicholasshook/.rvm/gems/Ruby-2.0.0-p247@pokerfund/gems/activesupport-4.0.0/lib/active_support/core_ext/object/to_json.rb:16:in `to_json'
from /Users/nicholasshook/.rvm/gems/Ruby-2.0.0-p247@pokerfund/gems/active_model_serializers-0.8.1/lib/active_model/serializer.rb:333:in `to_json'
from (irb):1
from /Users/nicholasshook/.rvm/gems/Ruby-2.0.0-p247@pokerfund/gems/railties-4.0.0/lib/Rails/commands/console.rb:90:in `start'
from /Users/nicholasshook/.rvm/gems/Ruby-2.0.0-p247@pokerfund/gems/railties-4.0.0/lib/Rails/commands/console.rb:9:in `start'
from /Users/nicholasshook/.rvm/gems/Ruby-2.0.0-p247@pokerfund/gems/railties-4.0.0/lib/Rails/commands.rb:64:in `<top (required)>'
私は単純にjson:Funding.allをレンダリングしたくありません。これは、このjsonをRailsアプリケーションで、angularjsアプリを使用して他のオブジェクトに渡したいからです。ありがとうございます。
今、あなたはこの方法でそれを行うことができます(AMS v0.10.2を使用して):
ActiveModel::Serializer.serializer_for(Funding.all).to_json
編集(2017年3月3日)
この方法はもう機能していません。 aNoble's answerを使用:
ActiveModelSerializers::SerializableResource.new(Funding.all).to_json
これがあなたが探しているものだと思います:
ActiveModel::ArraySerializer.new(Funding.all, each_serializer: FundingSerializer).to_json
例については、こちらをご覧ください Thoughtbot blog post .
これが慣用的な解決策であるかどうかはわかりませんが、うまくいくはずです:
Funding.all.map{|f| FundingSerializer.new(f)}.to_json
これはバージョン_0.10.2
_で機能しました:
ActiveModelSerializers::SerializableResource.new(Funding.all, each_serializer: FundingSerializer).to_json
コレクションシリアライザーも明示的に提供できます。
render json: Funding.all, serializer: ActiveModel::ArraySerializer, each_serializer: FundingSerializer
彼らは、最新のActiveModel :: Serializers gemバージョンでこれを再び調整しているように見えます。 ArraySerializer(ActiveModel :: Serializer :: ArraySerializerではありません)でto_jsonを呼び出すことはできなくなりました。
これを回避するために私がしたことは次のとおりです。
let(:resource) { Funding.all }
let(:serializer) { ActiveModel::Serializer::ArraySerializer.new(resource, each_serializer: FundingSerializer)
let(:serialization) { ActiveModel::Serializer::Adapter.create(serializer) }
subject { JSON.parse(serialization.to_json) }
件名を呼び出すと、目的のJSONが取得されます。
さらに読むためにテストのセットアップに飛び込むいくつかのリソースがあります: http://eclips3.net/2015/01/24/testing-active-model-serializer-with-rspec/ - https://robots.thoughtbot.com/validating-json-schemas-with-an-rspec-matcher
active_model_serializers
の応答をバージョン>= 0.10.0
でテストするRSpecのこの単純なヘルパーを実行しました。
module AMSHelper
def ams_array_serializer(collection, options: {}, adapter: :json)
serializer = ActiveModel::Serializer::ArraySerializer.new(collection)
adapter_class = ActiveModel::Serializer::Adapter.adapter_class(adapter)
adapter_class.new(serializer, options)
end
def ams_serializer(object, options: {}, adapter: :json)
serializer = ActiveModel::Serializer.serializer_for(object).new(object)
adapter_class = ActiveModel::Serializer::Adapter.adapter_class(adapter)
adapter_class.new(serializer, options)
end
end
RSpec.configure do |config|
config.include AMSHelper, type: :request
end
したがって、次のように簡単にテストできます。
RSpec.describe "Posts", type: :request do
describe "GET /" do
it "returns http success" do
get posts_path
expect(response_body).to eq(ams_array_serializer(Post.all).to_json)
end
end
end
これが誰かに役立つことを願っています。
リソース名(バー)と一致しないシリアライザークラス(Foo)があると仮定して、オブジェクトを簡単にシリアル化するために次のアプローチを使用します:
class BaseSerializer < ActiveModel::Serializer
def self.collection_serialize(resources)
ActiveModelSerializers::SerializableResource.new(resources, each_serializer: self)
end
end
fooシリアライザーにBaseSerializerを継承させます。
class FooSerializer < BaseSerializer
...
end
コントローラまたは外部でFooSerializerを使用します。
bar = Bar.all
FooSerializer.collection_serialize(bar).to_json