如何在特定控制器动作中排除AMS关联?能否传递params[:action]给BookSerializer?
针对特定控制器动作排除关联的解决方案
当然有更灵活的办法,不用每次都扩展新的Serializer子类来处理不同动作下的关联显示!下面分享两种直接把控制器动作信息传递给BookSerializer的方式:
方法1:在控制器渲染时显式传递动作参数
你可以在控制器的render方法里,直接把当前动作名称作为额外参数传给Serializer:
# 控制器代码 def index @books = Book.all render json: @books, serializer: BookSerializer, action_name: params[:action] end def show @book = Book.find(params[:id]) render json: @book, serializer: BookSerializer, action_name: params[:action] end
然后在BookSerializer里,通过instance_options获取这个参数,用条件判断决定是否包含关联:
# BookSerializer代码 class BookSerializer < ActiveModel::Serializer attributes :id, :title # 定义判断逻辑:只有非index动作才包含author关联 def include_author? instance_options[:action_name] != 'index' end has_one :author, if: :include_author? end
方法2:利用Serializer的context直接获取控制器动作
其实Serializer的context对象里默认包含了当前控制器实例,你可以直接从中读取动作名称,不用在控制器里额外传参:
# BookSerializer代码 class BookSerializer < ActiveModel::Serializer attributes :id, :title # 直接通过context判断动作,排除index动作下的author关联 has_one :author, unless: -> { context[:controller].action_name == 'index' } end
这种方式更简洁,省去了控制器里的参数传递步骤,直接在Serializer内部完成逻辑判断。
你当前通过扩展BookSerializer来处理的方式是完全可行的,但上面两种方法能帮你减少重复代码,让逻辑更集中在同一个Serializer里。
内容的提问来源于stack exchange,提问作者adavia
相关产品推荐
相关产品推荐

