Ruby on Rails:如何在JSON-API复合文档中向内部序列化器传参
解决jsonapi-serializer关联序列化器传参及全局数据传递问题
一、传递预获取的演员位置数据给ActorSerializer
在Movie控制器序列化对象时,通过params选项传入预获取的actor_locations,jsonapi-serializer会自动将参数传递给关联的ActorSerializer:
控制器实现示例
class MoviesController < ApplicationController def show movie = Movie.find(params[:id]) # 一次性拉取所有关联演员的位置数据,结构为 { 演员ID: 位置信息 } actor_ids = movie.actors.pluck(:id) actor_locations = ExternalLocationService.fetch_locations(actor_ids) # 序列化时传入params参数 render json: MovieSerializer.new(movie, params: { actor_locations: actor_locations }).serializable_hash end end
你的ActorSerializer已经实现了从params中读取actor_locations的逻辑,当请求携带include=actors时,关联的每个Actor实例都会自动获取到该参数,无需修改MovieSerializer的关联配置。
二、全局传递请求数据的方案
如果需要在多个序列化器中共享请求相关数据(如当前用户、请求参数等),可以采用以下两种方案:
1. 配置序列化器全局默认参数
在ApplicationController中设置全局默认参数,所有序列化器都会自动继承这些参数:
class ApplicationController < ActionController::API before_action :setup_serializer_defaults private def setup_serializer_defaults JSONAPI::Serializer.config.default_params = { current_user: current_user, request_query: request.query_parameters # 可添加其他需要全局共享的数据 } end end
之后在任意序列化器中,直接通过params[:current_user]即可访问全局传递的数据。
2. 使用线程局部变量
通过线程局部变量实现全局数据传递,需注意请求结束后清理数据,避免内存泄漏:
class ApplicationController < ActionController::API before_action :set_thread_local_data after_action :clear_thread_local_data private def set_thread_local_data Thread.current[:request_query] = request.query_parameters # 可在这里预加载全局需要的共享数据 end def clear_thread_local_data Thread.current[:request_query] = nil end end
在序列化器中直接读取线程变量:
attribute :current_location do |object| Thread.current[:actor_locations][object.id] end
内容的提问来源于stack exchange,提问作者Andrew Allaire
相关产品推荐
相关产品推荐

