J'essaie d'envoyer la version sérialisée d'un modèle à une vue en tant que paramètre, en utilisant la gemme active_model_serializers
#app/serializers/admin_serializer.rb
class AdminSerializer < ActiveModel::Serializer
attributes :id, :email, :access_locked?
end
#app/controllers/dashboard/admins_controller.rb
def index
@search = Admin.search(params[:q])
@admins = @search.result(:distinct => true).page(params[:page]).per(10)
@page_entries_info = view_context.page_entries_info @admins
# render json: @admins
respond_to do |format|
format.html
format.js
format.json {render json: @admins}
end
end
#app/views/dashboard/admins/index.html.erb
<%= debug (ActiveModel::Serializer::Adapter.adapter_class(:json_api).new(ActiveModel::Serializer.serializer_for(@admins.first).new(@admins.first),{}).to_json) %>
<%= debug (@admins.all.map{|admin| AdminSerializer.new(admin).to_json}) %>
Les débogages ci-dessus donnent la réponse ci-dessous:
--- '{"data":{"id":"1","type":"admins","attributes":{"email":"[email protected]","access_locked?":false}}}' //returned by the first debug
---
- '{"object":{"id":36,"email":"[email protected]","created_at":"2016-03-28T05:15:17.546Z","updated_at":"2016-03-28T05:15:17.546Z"},"instance_options":{},"root":null,"scope":null}'
- '{"object":{"id":20,"email":"[email protected]","created_at":"2016-03-28T05:15:16.304Z","updated_at":"2016-03-28T05:15:16.304Z"},"instance_options":{},"root":null,"scope":null}'
- '{"object":{"id":22,"email":"[email protected]","created_at":"2016-03-28T05:15:16.459Z","updated_at":"2016-03-28T05:15:16.459Z"},"instance_options":{},"root":null,"scope":null}'
- '{"object":{"id":37,"email":"[email protected]","created_at":"2016-03-28T05:15:17.624Z","updated_at":"2016-03-28T05:15:17.624Z"},"instance_options":{},"root":null,"scope":null}'
- '{"object":{"id":5,"email":"[email protected]","created_at":"2016-03-28T05:15:15.139Z","updated_at":"2016-03-28T05:15:15.139Z"},"instance_options":{},"root":null,"scope":null}'
- '{"object":{"id":14,"email":"[email protected]","created_at":"2016-03-28T05:15:15.838Z","updated_at":"2016-03-28T05:15:15.838Z"},"instance_options":{},"root":null,"scope":null}'
- '{"object":{"id":27,"email":"[email protected]","created_at":"2016-03-28T05:15:16.848Z","updated_at":"2016-03-28T05:15:16.848Z"},"instance_options":{},"root":null,"scope":null}'
- '{"object":{"id":2,"email":"[email protected]","created_at":"2016-03-28T05:15:14.873Z","updated_at":"2016-03-28T05:15:14.873Z"},"instance_options":{},"root":null,"scope":null}'
- '{"object":{"id":10,"email":"[email protected]","created_at":"2016-03-28T05:15:15.527Z","updated_at":"2016-03-28T05:15:15.527Z"},"instance_options":{},"root":null,"scope":null}'
- '{"object":{"id":15,"email":"[email protected]","created_at":"2016-03-28T05:15:15.916Z","updated_at":"2016-03-28T05:15:15.916Z"},"instance_options":{},"root":null,"scope":null}'
Dans le premier débogage, je sérialise un seul objet, tandis que dans le second j'essaie de le faire pour un tableau d'objets. Le premier débogage renvoie correctement la version sérialisée de l'objet (au format json_api) alors que le deuxième débogage ne l'est pas. J'ai également essayé ArraySerializer, sans succès: ActiveModel::Serializer::ArraySerializer.new(@admins, each_serializer: AdminSerializer).as_json
comment puis-je obtenir la sérialisation souhaitée. De plus, s'il est atteint, puis-je utiliser une autre version simplifiée de celui-ci? Comme cette déclaration de débogage est beaucoup trop verbeuse.
J'ai essayé toutes les solutions mentionnées ici - Comment initialiser une classe ActiveModel :: Serializer avec un tableau ActiveRecord :: Relation?
Le problème de base que j'essaie de résoudre est, dans la méthode d'indexation du contrôleur Admin, l'objet Admin est passé en tant que PORO au fichier index.html. Mais je veux la version json sérialisée de cet objet afin que je puisse la passer à mes composants Reaper en tant qu'accessoire
la méthode d'index rend le json correct lors du tir http://dashboard.localhost.com:3000/admins.json
MISE À JOUR # 1 pour la méthode d'index
def index
@search = Admin.search(params[:q])
@admins_array = @search.result(:distinct => true).to_a
if params[:page]
@admins = @search.result(:distinct => true).page(params[:page][:number]).per(10)
@admins_json_array = Kaminari.paginate_array(@admins_array).page(params[:page][:number]).per(10)
else
@admins = @search.result(:distinct => true).page(1).per(10)
@admins_json_array = Kaminari.paginate_array(@admins_array).page(1).per(10)
end
@admins_json = ActiveModel::SerializableResource.new(@admins_json_array.to_a)
...
...
...
end
J'ai un contrôleur dans lequel je dois spécifier le sérialiseur, car je souhaite avoir des attributs différents du sérialiseur par défaut.
Dans le contrôleur:
def index
search = User.ransack(search_params)
render json: search.result, each_serializer: MembershipRenewalSerializer::MemberSerializer
end
Donc, juste pour que les choses fonctionnent, que se passe-t-il si vous spécifiez le each_serializer
option?
Contrôleur extérieur:
ActiveModel::SerializableResource.new(
User.first(2),
each_serializer: MembershipRenewalSerializer::MemberSerializer
).to_json
Notez que sans spécifier each_serializer
, SerializableResource
utiliserait le UserSerializer
.
Il semble qu'il se passe quelque chose de bizarre avec les données @admins.
Essayez de convertir en tableau:
ActiveModel::SerializableResource.new(@admins.to_a).to_json
Pour paginer votre tableau, essayez ce qui suit:
@search = Admin.search(params[:q])
@results = @search.result(:distinct => true).to_a
@admins = Kaminari.paginate_array(@results).page(params[:page]).per(10)
Suivez le guide: Sérialisation avant le rendu du contrôleur
Vous pouvez utiliser ActiveModel::SerializableResource.new(@admins, adapter: :json_api).to_json
dans index.html.erb
<%= debug (ActiveModel::SerializableResource.new(@posts, adapter: :json_api).to_json) %>
ci-dessous est la sortie (en utilisant les messages)
'{"data":[{"id":"1","type":"posts","attributes":{"title":"first post","body":null}},{"id":"2","type":"posts","attributes":{"title":"second post","body":null}}],"links":{}}
Je crée un problème avec certaines méthodes d'assistance API et là, vous pouvez vérifier si c'est une passe de collection trouver le sérialiseur approprié et le passer au sérialiseur de collection.
def api_response(data)
render json: wrap_answer(data)
end
def wrap_answer(data)
if data.respond_to?(:each)
ActiveModel::Serializer::CollectionSerializer.new(data, each_serializer: ActiveModel::Serializer.serializer_for(data.first))
else
data
end
end