I have some objects in my DB that I like to render with a dedicated Hyperstack view Component.
Lets say my objects have a unique name
property from A to J. Now I would like to loop through them with each
and render a ComponentA
, ComponentB
, ComponentC
, ... depending on the name
of my object, and pass my object as a param to the component.
What I do now is:
DB_Objects.each do |object|
if object.name == 'A'
ComponentA(data: object)
elsif object.name == 'B'
ComponentB(data: object)
elsif object.name == 'C'
ComponentC(data: object)
elsif ...
What I want to do is something like:
DB_Objects.each do |object|
('Component' + object.name).constantize(data: object)
end
This is pseudo code as you can't give variables to constantize. But it shows what I would like to do.
How can I prevent a manual mapping of a object to its view.
Every component class defines a method of the same name as the class. When you say for example
ComponentA(data: object)
you are calling a method named ComponentA
that is tied the the ComponentA class.
So to dynamically reference the component you would use the send
method:
send('Component' + object.name, data: object)
Alternatively each component class has a class method insert_element
which will render an instance of the component class, and insert it into the rendering buffer. For example:
('Component' + object.name).constantize.insert_element(data: object)
I bring this up because while it is longer, you could use it to generalize this idea of yours (which I think is pretty cool)
class ApplicationRecord < ActiveRecord::Base
def render(opts = {})
('Component' + object.name).constantize.insert_element(opts, data: object)
end
end
Now you can say
some_record.render
Of course to generalize it like this you might want to use something other than name
. Anyway you could really have fun with this !