class ViewDelegates::ViewDelegate

Base class for delegates

Attributes

delegate_cache[RW]
polymorph_function[RW]

Public Class Methods

helpers_name() click to toggle source
# File lib/view_delegates/poros/view_delegate.rb, line 38
def self.helpers_name
  "#{to_s.gsub(/^.*::/, '')}".sub(/Delegate/, ''.freeze).concat('Helper').underscore
end
new(view_data = {}) click to toggle source

Initialize method @param [Hash] view_data hash containing all delegate properties

# File lib/view_delegates/poros/view_delegate.rb, line 30
def initialize(view_data = {})
  self.class.ar_models&.each do |t|
    send("#{t}=", view_data[t]) if view_data[t]
  end
  self.class.properties&.each do |t|
    send("#{t}=", view_data[t]) if view_data[t]
  end
end

Private Class Methods

cache(option, size: 50) click to toggle source

Activates cache on the view delegate option must be true/false size is an optional parameter, controls the max size of the cache array @param [Boolean] option @param [Integer] size

# File lib/view_delegates/poros/view_delegate.rb, line 114
def cache(option, size: 50)
  if option
    render_method = instance_method :render
    @delegate_cache = ViewDelegates::Cache.new(max_size: size)
    define_method(:render) do |view, local_params: {}, &block|
      value_key = "#{hash}#{local_params.hash}#{view.to_s}"
      result = self.class.delegate_cache.get value_key
      if result.nil?
        result = render_method.bind(self).call(view, local_params: local_params)
        self.class.delegate_cache.add key: value_key, value: result
      end
      if block
        block.call(result)
      else
        result
      end
    end
  end
end
helper(*methods) click to toggle source

Marks a method as view helper @param [Array(Symbol)] methods

# File lib/view_delegates/poros/view_delegate.rb, line 147
def helper(*methods)
  self.view_helpers += methods
end
model(method, properties: []) click to toggle source

The models this delegate will use @param [method] method The variable name this model will use @param [Array] properties The model properties to extract from the active record model

# File lib/view_delegates/poros/view_delegate.rb, line 171
def model(method, properties: [])
  attr_accessor method
  # Add the method name to the array of delegate models
  self.ar_models += [method]
  # Define a setter for the model
  define_method "#{method}=" do |val|
    # Create a struct with the model properties
    model_delegate = if properties.any?
                       Struct.new(*properties)
                     else
                       Struct.new(*val.attributes.keys)
                     end
    model_delegate = model_to_struct(val, model_delegate)
    # set the struct to instance model
    instance_variable_set(:"@#{method}", model_delegate)
  end
end
model_array(method, properties: []) click to toggle source
# File lib/view_delegates/poros/view_delegate.rb, line 189
def model_array(method, properties: [])
  attr_accessor method
  # Add the method name to the array of delegate models
  self.ar_models += [method]
  # Define a setter for the model
  define_method "#{method}=" do |model_array|
    # Create a struct with the model properties
    model_delegate = if properties.any?
                       Struct.new(*properties)
                     else
                       Struct.new(*val.attributes.keys)
                     end
    model_array.map! {|e| model_to_struct(e, model_delegate)}
    instance_variable_set(:"@#{method}", model_array)
  end
end
new(*args) click to toggle source

Override the new, we may need polymorphism @param [Hash] args

Calls superclass method
# File lib/view_delegates/poros/view_delegate.rb, line 95
def new(*args)
  if @polymorph_function
    command = super(*args)
    klazz = command.instance_eval(&@polymorph_function)
    if klazz == self
      super(*args)
    else
      klazz.new(*args)
    end
  else
    super
  end
end
polymorph(&block) click to toggle source

Polymorphism method The block must return the class we must use @param [Proc] block

# File lib/view_delegates/poros/view_delegate.rb, line 163
def polymorph &block
  @polymorph_function = block
end
property(*methods) click to toggle source

View properties @param [Symbol] method

# File lib/view_delegates/poros/view_delegate.rb, line 153
def property(*methods)
  methods.each do |method|
    attr_accessor method
  end
  self.properties += methods
end
view_local(*methods) click to toggle source

Marks a method as a view local @param [Symbol] method

# File lib/view_delegates/poros/view_delegate.rb, line 141
def view_local(*methods)
  self.view_locals += methods
end
view_path() click to toggle source

Gets the path for the delegate views

# File lib/view_delegates/poros/view_delegate.rb, line 135
def view_path
  @view_path ||= to_s.sub(/Delegate/, ''.freeze).underscore
end

Public Instance Methods

render(view, local_params: {}, &block) click to toggle source

Renders as a string the view passed as params @param [Symbol] view

# File lib/view_delegates/poros/view_delegate.rb, line 43
def render(view, local_params: {}, &block)
  locals = {}
  self.class.view_locals&.each do |method|
    locals[method] = send(method)
  end
  self.ar_models = {}
  self.view_helpers = {}
  self.class.ar_models&.each do |ar_model|
    ar_models[ar_model] = instance_variable_get(:"@#{ar_model}")
  end
  self.class.properties&.each do |property|
    locals[property] = instance_variable_get "@#{property}"
  end
  module_helpers = self.class.view_helpers
  module_methods = {}
  for method in module_helpers
    module_methods[method] = method(method)
  end
  helper_obj = Struct.new(self.class.helpers_name.camelcase) do

    module_helpers.each do |view_helper|
      define_method view_helper do |*args|
        module_methods[view_helper].call(*args)
      end
    end
  end.new
  locals = locals.merge(ar_models).merge(local_params)
  locals[self.class.helpers_name.to_sym] = helper_obj
  result = ViewDelegateController.render(self.class.view_path + '/' + view.to_s,
                                         locals: locals)

  if block
    block.call(result)
  else
    result
  end
end

Private Instance Methods

model_to_struct(model, struct) click to toggle source
# File lib/view_delegates/poros/view_delegate.rb, line 83
def model_to_struct(model, struct)
  initialize_hash = {}
  struct_members = struct.members
  struct_members.each do |k|
    initialize_hash[k] = model.send k
  end
  struct.new(*initialize_hash.values_at(*struct_members))
end