I have a common pattern or repeated code that I'd like to DRY up in my ActiveAdmin views. I'm using arbre components to render as much of my views as I can and I'd like to keep it that way if possible (i.e. I don't really want to convert to straight up HTML in the normal fashion -- I'm trying to understand the arbre way here). Here's the code I'd like to DRY up:
clients.in_groups_of(3).each do |clients_group|
columns do
clients_group.compact.each do |client|
column do
panel client.name do
# ...
end
end
end
end
end
After reading through the documentation in the arbre gem, I started to try to create my own, custom arbre component. But I was quickly forced to realize that I have no idea how to satisfy arbre. I couldn't figure out how to pass my local variables into the block. For example:
# config/initializers/active_admin.rb
module ActiveAdmin
module Views
class ClientsBreakdown < ActiveAdmin::Component
builder_method :clients_breakdown
def build(clients, attributes = {})
group_size = attributes.delete(:in_groups_of) { 3 }
clients.in_groups_of(group_size).each do |clients_group|
columns do
clients_group.compact.each do |client|
column do
panel client.name do
super(attributes) # Doesn't seem to matter where this `super` call
# is, but I do want to be able to pass `client`
# into the `clients_breakdown` block here
# yield(client) # -- I've also tried adding this.
end
end
end
end
end
end
end
end
end
Then, calling this in my ActiveAdmin User view might look like:
clients_breakdown(Client.all, in_groups_of: 2) do |client|
ul do
li client.name
end
end
Running the above code results in this error:
UPDATE 2 The exception has changed to this after moving my custom component code into the ActiveAdmin::Views
module.
My key issue seems to be that I can't just call yield(client)
where I currently have super(attributes)
. But that's an arbre thing so I don't know what to do there to pass the client into the calling block. Is this the right track or is there another way to DRY this up?
UPDATE 1
I've realized that the call to super
can happen anywhere in the build
method and really has nothing to do with what is output. So even if I move the super(attributes)
call up... I still can't figure out what to put inside of the panel
block so that I can render the rest of my arbre components in there from the call to clients_breakdown
.