首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用ActiveModel::Serializers进行有条件的侧加载

使用ActiveModel::Serializers进行有条件的侧加载
EN

Stack Overflow用户
提问于 2013-07-21 01:58:04
回答 3查看 4.9K关注 0票数 17

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

这样我就可以发出像GET /api/customers这样的请求

"customers": {
   "first_name": "Bill",
   "last_name": "Gates"
}

GET /api/customers?embed=address,note

"customers": {
   "first_name": "Bill",
   "last_name": "Gates"
},
"address: {
   "street": "abc"
},
"note": {
   "body": "Banned"
}

类似的东西取决于参数。我知道ActiveModel::Serializers具有include_[ASSOCIATION]?语法,但是我如何在我的控制器中有效地使用它呢?

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

customer_serializer.rb:

def include_address?
  !options[:embed].nil? && options[:embed].include?(:address)
end

application_controller.rb:

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

customers_controller.rb:

def show
  respond_with @customer, embed: embed_resources
end

一定是一种更简单的方法?

EN

回答 3

Stack Overflow用户

发布于 2013-07-24 00:53:02

我也在寻找一种有效和干净的方式来做到这一点。

我找到了一个解决方案,但它并不美观。

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

serialization_scope :params

因此,作用域现在是params Hash,我可以在序列化程序的include_[ASSOCIATION]?方法中使用它。

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

我不喜欢这个方法,因为如果我需要使用作用域来做其他事情,比如current_user来有条件地返回数据,例如它是管理员。

但这种解决方案在某些情况下是可行的。

更新

您可以传递view_context,而不是直接传递params

您可以在序列化程序中进行委托以保留scope名称而不是params名称。

在您的ApplicationController中:

serialization_scope :view_context

在序列化程序中:

delegate :params, to: :scope

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

票数 8
EN

Stack Overflow用户

发布于 2013-11-14 09:19:39

我还有另一个基于你的答案的解决方案,因为我想要类似的功能。根据文档,如果希望对关联序列化进行较低级别的控制,则可以覆盖include_associations!

例如:

def include_associations!
    if scope[:embed]
        include! :addresses, {embed: :ids, include: true}
    else
        include! :addresses, {embed: :ids}
    end
end
票数 2
EN

Stack Overflow用户

发布于 2015-03-02 02:04:12

对了解include_associations非常有帮助,谢谢!请注意,对于active_model_serializers gem (0.8.3版),您可以使用@options在控制器中设置上下文。例如,如果在控制器中调用

render json: customer, include_addresses: true

然后在CustomerSerializer中:

has_many :addresses
def include_associations!
  if @options[:include_addresses]
    include! :addresses
  end
end

然后这些地址将被序列化。如果在将include_addresses设置为false的情况下进行渲染,它们将不会显示。对于较新版本的active_model_serializers,请使用serialization_options而不是@options

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17765061

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档