2020 年更新:如果您使用 json_api 架构,active_model_serializer 现在支持此功能,但如果您使用 json 架构,文档还教您如何添加它。
文档在这里:https://github.com/rails-api/active_model_serializers/blob/v0.10.6/docs/howto/add_pagination_links.md
下面我将解释如果您使用json_api 或json 适配器,如何获得所需的结果。检查您在ActiveModelSerializers.config.adapter 上使用的是哪一个。
如果您使用 JSON API 适配器(您的 ActiveModelSerializers.config.adapter = :json_api)
分页链接将自动包含在您的回复中,只要
如果您使用的是JsonApi 适配器,则资源已分页。
如果您想在回复中添加分页链接,请使用Kaminari
或WillPaginate。
雷成例子
#array
@posts = Kaminari.paginate_array([1, 2, 3]).page(3).per(1)
render json: @posts
#active_record
@posts = Post.page(3).per(1)
render json: @posts
将分页示例
#array
@posts = [1,2,3].paginate(page: 3, per_page: 1)
render json: @posts
#active_record
@posts = Post.page(3).per_page(1)
render json: @posts
ActiveModelSerializers.config.adapter = :json_api
例如:
{
"data": [
{
"type": "articles",
"id": "3",
"attributes": {
"title": "JSON API paints my bikeshed!",
"body": "The shortest article. Ever.",
"created": "2015-05-22T14:56:29.000Z",
"updated": "2015-05-22T14:56:28.000Z"
}
}
],
"links": {
"self": "http://example.com/articles?page[number]=3&page[size]=1",
"first": "http://example.com/articles?page[number]=1&page[size]=1",
"prev": "http://example.com/articles?page[number]=2&page[size]=1",
"next": "http://example.com/articles?page[number]=4&page[size]=1",
"last": "http://example.com/articles?page[number]=13&page[size]=1"
}
}
ActiveModelSerializers 分页依赖于带有方法 current_page、total_pages 和 size 的分页集合,Kaminari 或 WillPaginate 都支持这些方法。
如果您使用的是 JSON 适配器(您的 ActiveModelSerializers.config.adapter = :json)
如果您没有使用JSON 适配器,则不会自动包含分页链接,但可以使用meta 键来实现。
将此方法添加到您的基本 API 控制器。
def pagination_dict(collection)
{
current_page: collection.current_page,
next_page: collection.next_page,
prev_page: collection.prev_page, # use collection.previous_page when using will_paginate
total_pages: collection.total_pages,
total_count: collection.total_count
}
end
然后,在你的渲染方法上使用它。
render json: posts, meta: pagination_dict(posts)
例如
{
"posts": [
{
"id": 2,
"title": "JSON API paints my bikeshed!",
"body": "The shortest article. Ever."
}
],
"meta": {
"current_page": 3,
"next_page": 4,
"prev_page": 2,
"total_pages": 10,
"total_count": 10
}
}
如果您有一个在元标记中添加分页信息的辅助方法,您也可以获得相同的结果。例如,在您的操作中指定一个自定义序列化程序。
render json: @posts, each_serializer: PostPreviewSerializer, meta: meta_attributes(@posts)
#expects pagination!
def meta_attributes(collection, extra_meta = {})
{
current_page: collection.current_page,
next_page: collection.next_page,
prev_page: collection.prev_page, # use collection.previous_page when using will_paginate
total_pages: collection.total_pages,
total_count: collection.total_count
}.merge(extra_meta)
end
属性适配器
此适配器不允许我们使用meta 键,因为无法添加分页链接。