我正在使用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
一定是一种更简单的方法?
发布于 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。
发布于 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
发布于 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
。
https://stackoverflow.com/questions/17765061
复制相似问题