使用ActiveModel :: Serializers有条件地进行侧载

Ric*_*ard 17 api json ruby-on-rails active-model-serializers

我正在使用ActiveModel :: Serializers构建API .使用params有条件地侧载数据的最佳方法是什么?

所以我可以提出如下请求GET /api/customers:

"customers": {
   "first_name": "Bill",
   "last_name": "Gates"
}
Run Code Online (Sandbox Code Playgroud)

GET /api/customers?embed=address,note

"customers": {
   "first_name": "Bill",
   "last_name": "Gates"
},
"address: {
   "street": "abc"
},
"note": {
   "body": "Banned"
}
Run Code Online (Sandbox Code Playgroud)

这样的东西取决于params.我知道ActiveModel :: Serializers有include_[ASSOCIATION]?语法,但我如何从我的控制器有效地使用它?


这是我目前的解决方案,但它并不整洁:

customer_serializer.rb:

def include_address?
  !options[:embed].nil? && options[:embed].include?(:address)
end
Run Code Online (Sandbox Code Playgroud)

application_controller.rb:

def embed_resources(resources = [])
  params[:embed].split(',').map { |x| resources << x.to_sym } if params[:embed]
  resources
end
Run Code Online (Sandbox Code Playgroud)

customers_controller.rb:

def show
  respond_with @customer, embed: embed_resources
end
Run Code Online (Sandbox Code Playgroud)

必须是一个更简单的方法?

lou*_*lou 8

我也在寻找一种有效而干净的方法来做到这一点.

我找到了一个解决方案,但它并不漂亮.

在我的BaseController/ApplicationController中,我添加了这个方法:

serialization_scope :params
Run Code Online (Sandbox Code Playgroud)

所以范围现在是params Hash,我可以在include_[ASSOCIATION]?我的序列化器的方法中使用它.

def include_associations?
    if scope[:embed]
        embed = scope[:embed].split(',') 
        return true if embed.include?('associations')
    end
end
Run Code Online (Sandbox Code Playgroud)

我不喜欢这种方法,因为如果我需要将范围用于其他类似的东西,比如current_user有条件地返回数据,如果它是管理员的话.

但是这个解决方案在某些情况下可以工作

UPDATE

你可以传球view_context而不是直接传球params.

您可以在Serializer中委托保留params名称而不是scope.

在您的ApplicationController中:

serialization_scope :view_context
Run Code Online (Sandbox Code Playgroud)

在你的序列化器中:

delegate :params, to: :scope
Run Code Online (Sandbox Code Playgroud)

瞧,您可以在include_[ASSOCIATION]?序列化程序的方法中使用params [:embed] .