Skip to content

Make callable classes to use instead of blocks #2904

Open
@adrianthedev

Description

@adrianthedev

In Avo we use blocks in many places and one of the caveats we noticed is that it's difficult to DRY them up. You'd have to create a new class or module, then a method and that method to return a block, which is not very nice.

module Extracted
  def formatter
    -> { format_this_value value }
  end
end

field :name, as: :name, format_using: Extracted.formatter

We'd like to use anonymous classes for that

class Hey
  def self.call
    value.downcase
  end

  def self.to_proc
    method(:call).to_proc
  end
end

field :name, as: :name, format_using: Hey

This strategy should work, but it might give us trouble in blocks where we use nesting.

# avo.rb

self.main_menu = -> {
  section do
    group "name" do
      link_to ...
    end
  end
}

We need to do some kind of sorcery to support that. I believe @Paul-Bob did it with def fields.

We also need to abstract away some of that boilerplate, including the self.to_proc method.

I'm thinking about providing a class which the users can extend and just add their own call method on it and we can do the "sorcery" and the to_proc.

class Hey < Avo::BaseSomething
  def self.call
    value.downcase
  end
end

field :name, as: :name, format_using: Hey
field :city, as: :name, format_using: Hey

In the menu example users can do something like this:

  if user.admin?
    AdminMenu.new(user).build
  elsif user.manager?
    ManagerMenu.new(user).build
  else
    OtherMenu.new(user).build
  end

# config.main_menu = Hey

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    Triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions