简体   繁体   English

使用 active_model_serializers 序列化模型数组

[英]Serialize an array of models using active_model_serializers

I am trying to send the serialized version of a model to a view as a param, using the gem active_model_serializers我正在尝试使用 gem 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}) %>

Above debugs are yielding the below response:以上调试产生以下响应:

--- '{"data":{"id":"1","type":"admins","attributes":{"email":"tech@bluesapling.com","access_locked?":false}}}' //returned by the first debug


---
- '{"object":{"id":36,"email":"aubrey_schmitt@feeneykoch.io","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":"alysa_johnston@thompson.io","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":"kristofer.langosh@kunzeluettgen.com","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":"beryl_keler@wiza.biz","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":"wilhelmine_buckridge@crona.io","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":"edward_wisoky@corkery.net","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":"leonor@jerde.biz","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":"carley@wyman.net","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":"ervin.gleichner@cremin.org","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":"lonzo.dickens@johnscole.name","created_at":"2016-03-28T05:15:15.916Z","updated_at":"2016-03-28T05:15:15.916Z"},"instance_options":{},"root":null,"scope":null}'

In the first debug I am serializing only one object, while in the second one I am trying to do it for an array of objects.在第一个调试中,我只序列化一个对象,而在第二个调试中,我试图对一组对象进行序列化。 The first debug is correctly returning the serialized version of the object(in json_api format) while second debug is not.第一个调试正确返回对象的序列化版本(以 json_api 格式),而第二个调试则没有。 Tried ArraySerializer as well, with no success: ActiveModel::Serializer::ArraySerializer.new(@admins, each_serializer: AdminSerializer).as_json how do I achieve the desired serialization.也尝试了 ArraySerializer,但没有成功: ActiveModel::Serializer::ArraySerializer.new(@admins, each_serializer: AdminSerializer).as_json如何实现所需的序列化。 Moreover, if achieved, can I used some other simplified version of this?此外,如果实现了,我可以使用其他一些简化版本吗? As this debug statement is way too verbose.因为这个调试语句太冗长了。

Tried all the solutions mentioned here - How do you initialize an ActiveModel::Serializer class with an ActiveRecord::Relation array?尝试了这里提到的所有解决方案 - 如何使用 ActiveRecord::Relation 数组初始化 ActiveModel::Serializer 类?

The basic problem which I am trying to solve is, in the index method of the Admin controller, the Admin object is passed as a PORO to the index.html file.我试图解决的基本问题是,在 Admin 控制器的 index 方法中,Admin 对象作为 PORO 传递给 index.html 文件。 But I want the serialized json version of this object so that I can pass it to my react components as a prop但我想要这个对象的序列化 json 版本,以便我可以将它作为道具传递给我的反应组件

index method is rendering proper json on firing http://dashboard.localhost.com:3000/admins.json index 方法在触发http://dashboard.localhost.com:3000/admins.json 时呈现正确的 json 在此处输入图片说明

UPDATE#1 for the index method索引方法的更新#1

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

I have a controller that I need to specify the serializer in, due to wanting different attributes from the default serializer.我有一个控制器,我需要在其中指定序列化程序,因为需要与默认序列化程序不同的属性。

In Controller:在控制器中:

  def index
    search = User.ransack(search_params)
    render json: search.result, each_serializer: MembershipRenewalSerializer::MemberSerializer
  end

So, just to get things working, what happens if you specify the each_serializer option?所以,只是为了让事情正常工作,如果指定each_serializer选项会发生什么?

Edits:编辑:

Outside Controller:外部控制器:

ActiveModel::SerializableResource.new(
  User.first(2), 
  each_serializer: MembershipRenewalSerializer::MemberSerializer
).to_json

Note, that without specifying each_serializer , SerializableResource would use the UserSerializer .请注意,如果不指定each_serializerSerializableResource将使用UserSerializer

Edit #2,编辑#2,

It looks like there is something weird happening with the @admins data. @admins 数据似乎发生了一些奇怪的事情。

Try converting to an array:尝试转换为数组:

ActiveModel::SerializableResource.new(@admins.to_a).to_json 

Edit #3编辑 #3

To paginate your array, try the following:要对数组进行分页,请尝试以下操作:

@search = Admin.search(params[:q])
@results = @search.result(:distinct => true).to_a
@admins = Kaminari.paginate_array(@results).page(params[:page]).per(10)

Follow the guide: Serializing before controller render遵循指南: 在控制器渲染之前序列化

You could use ActiveModel::SerializableResource.new(@admins, adapter: :json_api).to_json您可以使用ActiveModel::SerializableResource.new(@admins, adapter: :json_api).to_json

in index.html.erbindex.html.erb

<%= debug (ActiveModel::SerializableResource.new(@posts, adapter: :json_api).to_json) %>

below is the output(using posts)下面是输出(使用帖子)

'{"data":[{"id":"1","type":"posts","attributes":{"title":"first post","body":null}},{"id":"2","type":"posts","attributes":{"title":"second post","body":null}}],"links":{}}

I create a concern with some API helper methods and there you can check if its a collection pass find the appropiate serializer and pass it to the collection serializer.我对一些 API 帮助程序方法产生了关注,您可以在那里检查它的集合传递是否找到了合适的序列化程序并将其传递给集合序列化程序。

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

应该把它变成字符串并使用 json.stringify 把它变成一个字符串,让你的生活更轻松

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用active_model_serializers将模型序列化到Rails中的json字段 - Serializing models to a json field in Rails using active_model_serializers 使用active_model_serializers序列化权限(例如CanCan) - Serialize permissions (e.g. CanCan) with active_model_serializers active_model_serializers关联为: - active_model_serializers association as: 使用active_model_serializers时如何自定义集合渲染? - How to customize collection rendering when using active_model_serializers? 如何使用active_model_serializers获取嵌套属性 - How to get nested attributes using active_model_serializers 使用active_model_serializers将方法应用于所有属性 - Apply method to all attributes using active_model_serializers 与active_model_serializers的条件链接 - Conditional links with active_model_serializers Rails active_model_serializers 不工作 - Rails active_model_serializers not working 使用Rails序列化器(active_model_serializers)基于增量主键呈现键/值对 - Using Rails Serializers (active_model_serializers) to render key/value pairs based on incremental primary keys 解决使用devise_token_auth和active_model_serializers发行多个用户模型的问题? - Work around for issue multiple user models with devise_token_auth and active_model_serializers?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM