【问题标题】:ActiveModel Serializer - Passing params to serializersActiveModel 序列化器 - 将参数传递给序列化器
【发布时间】:2017-11-30 04:31:25
【问题描述】:

AMS 版本:0.9.7

我正在尝试将参数传递给 ActiveModel 序列化程序,但没有任何运气。

我的(精简的)控制器:

class V1::WatchlistsController < ApplicationController
  
   def index
     currency = params[:currency]
     @watchlists = Watchlist.belongs_to_user(current_user)
     render json: @watchlists, each_serializer: WatchlistOnlySerializer
   end

我的序列化器:

class V1::WatchlistOnlySerializer < ActiveModel::Serializer
  attributes :id, :name, :created_at, :market_value
  attributes :id

  
  def filter(keys)
    keys = {} if object.active == false 
    keys
  end 
  
  private

  def market_value
    # this is where I'm trying to pass the parameter
    currency = "usd"
    Balance.watchlist_market_value(self.id, currency)
  end

我正在尝试将参数 currency 从控制器传递到序列化程序,以便在 market_value 方法中使用(在示例中被硬编码为“usd”)。

我已经尝试过@options 和@instance_options,但我似乎无法让它发挥作用。不确定它是否只是语法问题。

【问题讨论】:

    标签: ruby-on-rails active-model-serializers


    【解决方案1】:

    AMS 版本:0.10.6

    传递给render 的任何未为adapter 保留的选项在序列化程序中都可以作为instance_options 使用。

    在您的控制器中:

    def index
      @watchlists = Watchlist.belongs_to_user(current_user)
      render json: @watchlists, each_serializer: WatchlistOnlySerializer, currency: params[:currency]
    end
    

    然后你可以像这样在序列化器中访问它:

    def market_value
      # this is where I'm trying to pass the parameter
      Balance.watchlist_market_value(self.id, instance_options[:currency])
    end
    

    文档:Passing Arbitrary Options To A Serializer


    AMS 版本:0.9.7

    不幸的是,对于这个版本的 AMS,没有明确的方法可以将参数发送到序列化程序。但是您可以使用:scope (as Jagdeep said) 或:contextfollowing accessors 之外的任何关键字来破解它:

    attr_accessor :object, :scope, :root, :meta_key, :meta, :key_format, :context, :polymorphic
    

    虽然我更喜欢 :context 而不是 :scope 对于这个问题的目的,如下所示:

    在您的控制器中:

    def index
      @watchlists = Watchlist.belongs_to_user(current_user)
      render json: @watchlists,
        each_serializer: WatchlistOnlySerializer,
        context: { currency: params[:currency] }
    end
    

    然后你可以像这样在序列化器中访问它:

    def market_value
      # this is where I'm trying to pass the parameter
      Balance.watchlist_market_value(self.id, context[:currency])
    end
    

    【讨论】:

    • 这一错误:NameError (undefined local variable or method 'instance_options' for #&lt;V1::WatchlistOnlySerializer:0x007fb9c06e4638&gt;
    • 请问您的 AMS 版本?
    • AMS 版本 0.9.7
    • 更新了我对此版本的回答。请查看。
    • 我在 0.10.9,没有这样的方法。
    【解决方案2】:

    尝试在控制器中使用scope

    def index
     @watchlists = Watchlist.belongs_to_user(current_user)
     render json: @watchlists, each_serializer: WatchlistOnlySerializer, scope: { currency: params[:currency] }
    end
    

    在你的序列化器中:

    def market_value
      Balance.watchlist_market_value(self.id, scope[:currency])
    end
    

    【讨论】:

    • 这行得通。 Wasif Hossain 有更彻底的解释。
    【解决方案3】:

    您可以像这样将参数发送到您的序列化程序

    render json: @watchlists, each_serializer: WatchlistOnlySerializer, current_params: currency
    

    在您的序列化程序中,您可以使用它来获取值

    serialization_options[:current_params]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-03
      • 2016-10-28
      • 2019-07-25
      • 1970-01-01
      • 2021-06-20
      • 2015-11-02
      • 2016-12-22
      • 1970-01-01
      相关资源
      最近更新 更多