class ViewModel::Registry
def all
def all @lock.synchronize do resolve_deferred_classes @viewmodel_classes_by_name.values end end
def clear_removed_classes!
For Rails hot code loading: ditch any classes that are not longer present at
def clear_removed_classes! @lock.synchronize do resolve_deferred_classes @viewmodel_classes_by_name.delete_if do |_name, klass| !Kernel.const_defined?(klass.name) end end end
def default_view_name(model_class_name)
def default_view_name(model_class_name) model_class_name.gsub('::', '.') end
def for_view_name(name)
def for_view_name(name) raise ViewModel::DeserializationError::InvalidSyntax.new('ViewModel name cannot be nil') if name.nil? @lock.synchronize do # Resolve names for any deferred viewmodel classes resolve_deferred_classes viewmodel_class = @viewmodel_classes_by_name[name] if viewmodel_class.nil? || !(viewmodel_class < ViewModel) raise ViewModel::DeserializationError::UnknownView.new(name) end viewmodel_class end end
def infer_model_class_name(view_name)
def infer_model_class_name(view_name) view_name.gsub('.', '::') end
def initialize
def initialize @lock = Monitor.new @viewmodel_classes_by_name = {} @deferred_viewmodel_classes = [] end
def register(viewmodel, as: DEFERRED_NAME)
def register(viewmodel, as: DEFERRED_NAME) @lock.synchronize do @deferred_viewmodel_classes << [viewmodel, as] end end
def resolve_deferred_classes
def resolve_deferred_classes until @deferred_viewmodel_classes.empty? vm, view_name = @deferred_viewmodel_classes.pop if vm.should_register? view_name = vm.view_name if view_name == DEFERRED_NAME @viewmodel_classes_by_name[view_name] = vm end end end
def roots
def roots all.select { |c| c.root? } end