2

我将 Draper 用于一般视图层装饰器。

我有一些与控制台相关的、人类可读的功能,我想将其引入新的装饰器中。

我的第一个想法是将它们放在一个模块中,例如,Human::XxxDecorator使它们与我的普通视图层装饰器隔离:它们只是用于rails c调试/黑客/测试工作。

这在顶层运行良好;我可以使用命名空间装饰器显式装饰模型。

现在我需要装饰一系列 STI 车辆。我不确定在同一个装饰器模块中创建特定于车辆类型的装饰器的最佳方法是什么,例如,我有:

  • Human::CarDecorator
  • Human::TruckDecorator
  • Human::MotorcycleDecorator

我不知道如何从,例如,

pry » dfleet = Human::FleetDecorator.new(Fleet.find(1))

Human到其嵌入的车辆集合,每个车辆都有来自模块的适当装饰器。使用天真的方法decorates不起作用;我得到:

Draper::UninferrableDecoratorError: Could not infer a decorator for Vehicle

组合:

  • 来自特定模块的装饰器,以及
  • 适合 STI 模型的装饰器

正在扔东西。

在深入研究 Draper 装饰器推理代码之前(我只是假设这是最好的起点),这是一个已经解决的问题并且我遗漏了一些东西吗?

4

3 回答 3

4

正如我在评论中所写,移除车辆的内置装饰,并编写代码:

def vehicles
  object.vehicles.map do |v|
    # logic to instantiate proper decorator
  end
end 

黑客入侵:

module Human
  class FleetDecorator < Draper::Decorator
    decorates_association :vehicles, with: ::Human::VehicleDecoratorDispatcher
  end

  class VehicleDecoratorDispatcher < Draper::Decorator
    def initialize(*args)
      super
      @object = ... # here you build the proper decorator based on the rules on @object
    end

  end
end

但我怀疑这是否更清楚......

于 2014-06-16T19:33:32.950 回答
1

您可以使用常量化:

def dfleet
  dfleet_decorator_class.new(object.dfleet)
end

def dfleet_decorator_class
  "#{object.dfleet.class}Decorator".constantize
end
于 2014-11-05T04:46:05.807 回答
0

使用装饰:. 这是一个例子:点击

于 2014-10-12T22:02:37.277 回答