呈現我的問題的假想簡化版本。想象一下,我有一個網站,用戶可以用自己的品牌創建一個商店,並從產品目錄中選擇要顯示在他們的商店。商店&產品有一個擁有和屬於多(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