Reputation: 160261
I'm using Draper for general view-layer decorators.
I have some console-related, human-readability functionality I'd like to pull into new decorators.
My first thought was to put them in a module, e.g., Human::XxxDecorator
, keeping them isolated from my normal view-layer decorators: they're just for rails c
debugging/hacking/testing work.
This works fine at the top level; I can explicitly decorate a model with the namespaced decorator.
Now I need to decorate a collection of STI vehicles. I'm not sure what the best way to create vehicle-type-specific decorators in the same module of decorators, e.g., I have:
Human::CarDecorator
Human::TruckDecorator
Human::MotorcycleDecorator
I'm not sure how to get from, e.g.,
pry » dfleet = Human::FleetDecorator.new(Fleet.find(1))
to its embedded collections of vehicles, each with an appropriate decorator from the Human
module. The naive approach using decorates
doesn't work; I get:
Draper::UninferrableDecoratorError: Could not infer a decorator for Vehicle
The combination of:
is throwing things off.
Before digging into the Draper decorator inference code (I'm only assuming that's the best place to start), is this a problem that's already been solved and I'm missing something?
Upvotes: 2
Views: 1459
Reputation: 1121
You could use constantize:
def dfleet
dfleet_decorator_class.new(object.dfleet)
end
def dfleet_decorator_class
"#{object.dfleet.class}Decorator".constantize
end
Upvotes: 1
Reputation: 115541
As I wrote in comments, remove the builtin decoration of your vehicles, and code yours:
def vehicles
object.vehicles.map do |v|
# logic to instantiate proper decorator
end
end
Hack incoming:
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
But I doubt this is clearer...
Upvotes: 4