呈现我的问题的假想简化版本。想象一下,我有一个网站,用户可以用自己的品牌创建一个商店,并从产品目录中选择要显示在他们的商店。商店&产品有一个拥有和属于多(HABTM)的关系。每种产品都有自己的特定商店路线。访问ActiveModelSerializers中Child序列化程序中的父对象
Rails.application.routes.draw do
resources :shops do
resources :products
end
end
class ShopSerializer < ActiveModel::Serializer
has_many :products
end
class ProductSerializer < ActiveModel::Serializer
include Rails.application.routes.url_helpers
attribute :url do
shop_product_url(NEED SHOP ID, product_id: object.id)
end
end
当一个店铺被序列化,并作为一个结果,所以是其产品的回收,我想产品串行要知道,是其序列的店铺,并用它来包含在路线序列化输出。这怎么可能?我试过所有从ShopSerializer
传递instance_options
的方式,但它不能按预期工作。
# this works except is apparently not threadsafe as multiple
# concurrent requests lead to the wrong shop_id being used
# in some of the serialized data
has_many :products do
ActiveModelSerializers::SerializableResource.new(shop_id: object.id).serializable_hash
end
# shop_id isn't actually available in instance_options
has_many :products do
ProductSerializer.new(shop_id: object.id)
end
解决方案#1伟大的工作(没有尝试#2),只是我不得不打电话'Rails.application.routes.url_helpers.shop_product_url'否则我'NoMethodError(未定义的方法 'shop_product_url' 为#<::加载ActiveModel Serializer :: HasManyReflection:0x007fde59072670>)(甚至在串行器中包含Rails.application.routes.url_helpers) – swrobel
我敢打赌,block是'instance_eval'ed,这就是为什么它不能访问包含的帮助器。您可以尝试在顶部使用'url_helpers = Rails.application.routes.url_helpers',并在模块内部使用'url_helpers.shop_product_url(...)',以获得更干净的解决方案。 –
不幸的是,这实际上并不是线程安全的。我希望我对此有一些很好的见解,但实质上问题是,如果在不同商店的不同Puma线程上同时发出两个请求,第二个请求将使用第一个'object.id'又名'Shop#id' 。我无法写出失败的测试,但我在生产中可靠地看到它。尚未测试第二个解决方案... – swrobel