我正在使用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
组合:
放弃了。
在深入研究Draper装饰器推理代码之前(我只是假设这是最好的起点),这是一个已经解决的问题而且我错过了什么?
答案 0 :(得分: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
但我怀疑这更清楚......
答案 1 :(得分:1)
您可以使用constantize:
def dfleet
dfleet_decorator_class.new(object.dfleet)
end
def dfleet_decorator_class
"#{object.dfleet.class}Decorator".constantize
end
答案 2 :(得分:0)
使用装饰:。以下是一个示例:CLICK