class Para::ComponentsConfiguration

Public Instance Methods

component_configuration_for(identifier) click to toggle source
# File lib/para/components_configuration.rb, line 59
def component_configuration_for(identifier)
  sections.each do |section|
    section.components.each do |component|
      # If one of the section component has the searched identifier return it
      return component if component.identifier.to_s == identifier.to_s

      component.child_components.each do |child_component|
        # If one of the component children has the searched identifier return it
        return child_component if child_component.identifier.to_s == identifier.to_s
      end
    end
  end

  # Return nil if the identifier was not found
  nil
end
component_for(identifier) click to toggle source
# File lib/para/components_configuration.rb, line 47
def component_for(identifier)
  if (component = components_cache[identifier])
    component
  else
    components_cache[identifier] = if (component_id = components_ids_hash[identifier])
                                     Para::Component::Base.find(component_id)
                                   else
                                     Para::Component::Base.find_by(identifier: identifier)
                                   end
  end
end
components_ids_hash() click to toggle source
# File lib/para/components_configuration.rb, line 80
def components_ids_hash
  @components_ids_hash ||= {}.with_indifferent_access
end
draw(&block) click to toggle source
# File lib/para/components_configuration.rb, line 6
def draw(&block)
  return unless components_installed?

  Para::LogConfig.with_log_level(:fatal) do
    log_level = Rails.logger.level
    Rails.logger.level = :fatal

    eager_load_components!
    instance_eval(&block)
    build
  end
end
method_missing(method, *args, &block) click to toggle source
Calls superclass method
# File lib/para/components_configuration.rb, line 27
def method_missing(method, *args, &block)
  if (component = component_for(method))
    component.tap(&ActiveDecorator::Decorator.instance.method(:decorate))
  else
    super
  end
end
section(*args, &block) click to toggle source
# File lib/para/components_configuration.rb, line 19
def section(*args, &block)
  sections << Section.new(*args, &block)
end
section_for(identifier) click to toggle source
# File lib/para/components_configuration.rb, line 35
def section_for(identifier)
  if (section = sections_cache[identifier])
    section
  else
    sections_cache[identifier] = if (section_id = sections_ids_hash[identifier])
                                   Para::ComponentSection.find(section_id)
                                 else
                                   Para::ComponentSection.find_by(identifier: identifier)
                                 end
  end
end
sections() click to toggle source
# File lib/para/components_configuration.rb, line 23
def sections
  @sections ||= []
end
sections_ids_hash() click to toggle source
# File lib/para/components_configuration.rb, line 76
def sections_ids_hash
  @sections_ids_hash ||= {}.with_indifferent_access
end

Private Instance Methods

build() click to toggle source
# File lib/para/components_configuration.rb, line 86
def build
  sections.each_with_index do |section, index|
    section.refresh(position: index)
    sections_ids_hash[section.identifier] = section.model.id

    section.components.each do |component|
      components_ids_hash[component.identifier] = component.model.id

      component.child_components.each do |child_component|
        components_ids_hash[child_component.identifier] = child_component.model.id
      end
    end
  end
end
components_cache() click to toggle source

Only store components cache for the request duration to avoid expired references to AR objects between requests

# File lib/para/components_configuration.rb, line 111
def components_cache
  RequestStore.store[:components_cache] ||= {}.with_indifferent_access
end
components_installed?() click to toggle source
# File lib/para/components_configuration.rb, line 115
def components_installed?
  tables_exist = %w[component/base component_section].all? do |name|
    Para.const_get(name.camelize).table_exists?
  end

  unless tables_exist
    Rails.logger.warn(
      "Para migrations are not installed.\n" \
      'Skipping components definition until next app reload.'
    )
  end

  tables_exist
rescue ActiveRecord::NoDatabaseError
  false # Do not load components when the database is not installed
end
eager_load_components!() click to toggle source

Eager loads every file ending with _component.rb that’s included in a $LOAD_PATH directory which ends in “/components”

Note : This allows not to process too many folders, but makes it harder to plug gems into the components system

# File lib/para/components_configuration.rb, line 138
def eager_load_components!
  $LOAD_PATH.each do |path|
    next unless path.match(%r{/#{Para.config.components_directory}$})

    glob = File.join(path, '**', '*_component.rb')

    Dir[glob].each do |file|
      load(file)
    end
  end
end
sections_cache() click to toggle source

Only store sections cache for the request duration to avoid expired references to AR objects between requests

# File lib/para/components_configuration.rb, line 104
def sections_cache
  RequestStore.store[:sections_cache] ||= {}.with_indifferent_access
end