根据使用 ROAR gem 的标准为同一 class 创建多个表示的策略?

Strategy to create multiple representations for the same class based on criteria using ROAR gem?

这实际上是关于在 Rails 中使用 Roar & representable 的最佳实践/使用问题,因为我没有找到任何相关示例。这里有两种情况。我使用装饰器模式。

场景 1:

假设我有一个具有多个属性和关联的产品 class。默认情况下,当有人向 api.com/products/1 发出请求时 - 我想展示我所拥有的一切,但如果有人向 api.[=44 这样的其他操作发出请求=]/inventory_details - 我只想显示与库存有关的有限视图(以便更快地进行库存查找)或者如果有人向 api.com/products/1/assembly_details - 我想要 return 相关子组件矩阵以及一些相关产品详细信息。

场景 1 的问题:

  1. 我是为每个案例创建一个特定的代表,如 ProductRepresenter、ProductInventoryDe​​tailRepresenter、ProductAssemblyDetailRepresenter,还是在 ProductRepresenter 中使用某种流控制?
  2. 如果我为同一个 class 创建多个代表,我如何使用代表 / respond_with 模式与 respond_to / 渲染?
  3. 我可以在操作级别覆盖它吗?

场景 2:

假设我有 api.com/products/1 我的内部应用程序可以调用但我也想向我的客户公开。但是,我不希望我的客户看到某些属性,例如库存详细信息或可能只是一两个属性。另外,根据员工的访问级别,我想限制他们的视图/表示。

场景 2 的问题:

  1. 我是为每个案例创建一个特定的代表,如 ProductRepresenter、ProductClientViewRepresenter,还是在 ProductRepresenter 中使用某种流量控制?
  2. 如果我为同一个 class 创建多个代表,我如何使用代表 / respond_with 模式与 respond_to / 渲染?
  3. 我能否在操作级别覆盖它 - 基于访问类型,例如:管理员 vs inventory_user vs shipping_user?

如有任何建议,我们将不胜感激。 (我将在 Roar-Rails gem 中的 github 上交叉-post)

场景 1:

  1. Do I create a specific representer for each case like ProductRepresenter, ProductInventoryDetailRepresenter, ProductAssemblyDetailRepresenter or do I use some kind of flow control in the ProductRepresenter?

是的,请使用单独的 classes。不要以 if: 和 else 以及那种在 vanilla Rails 中完成的废话开头。我认为每个上下文一个代表 class 是正确的。但是,您应该使用模块并将它们包含到装饰器中以共享公共属性。

  1. If I create multiple representers, for the same class, how can I use represents / respond_with pattern vs respond_to / render ?

你可以使用 ::represents 来表示,见 roar-rails.

  1. Can I override this on action level?

再次检查 roar-respond_withrender 的文档-rails,它们允许明确设置代表。

场景 2 的问题:

  1. Do I create a specific representer for each case like ProductRepresenter, ProductClientViewRepresenter or do I use some kind of flow control in the ProductRepresenter?

如果只是隐藏某些属性,您实际上可以尝试使用 :if 并将上下文注入 rendering/parsing 调用。

object.to_json(context: "admin")

property :title, if: ->(options) { options[:context] == "admin" }

但是,我强烈反对 :if 总的来说,因为它总是以一堆乱七八糟的决策者告终。在 github 上打我,也许我们可以找到一种方法来在一般层面上解决这个问题,使用上下文或类似的方法?

  1. 和 3.,见上文。