Skip to content

Instantly share code, notes, and snippets.

@chsh
Created June 4, 2021 11:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chsh/6afa7bb3c7dff7a71b81cb50f3e32686 to your computer and use it in GitHub Desktop.
Save chsh/6afa7bb3c7dff7a71b81cb50f3e32686 to your computer and use it in GitHub Desktop.
ViewComonent helper using DSL flavor.
# usage:
# = render vc.path1.path2(:name, arg1: 'a')
# or
# = render vc('path1/path2/name', arg1: 'a')
module ViewComponentHelper
class VisualComponentChainer
def initialize
@nest = []
end
def __view_component__(name, *args)
name_with_package = (@nest + [name]).join('/')
component_klass = "#{name_with_package}_component".classify.constantize
params = args.extract_options!
if args.size == 0
component_klass.new **params
elsif args.size == 1 && args[0].is_a?(Enumerable)
component_klass.with_collection args[0], **params
else
raise "Unacceptable input: args.size=#{args.size}, args=#{args}, params=#{params}"
end
end
def method_missing(symbol, *args)
if symbol.to_s =~ /^[a-z][a-z\d_]+$/
self.class.class_eval do
define_method symbol do |*params|
@nest << symbol
if params.size == 0
self
else
name = params.shift
__view_component__(name, *params)
end
end
end
__send__(symbol, *args)
else
super
end
end
end
def vc(*args)
vcc = VisualComponentChainer.new
if args.size == 0
vcc
else
name = args.shift
vcc.__view_component__(name, *args)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment