Sha256: efeade06ec332b34903d894054da2f9256942e7ea6587f8d7ac74296bae67a30

Contents?: true

Size: 1.38 KB

Versions: 4

Compression:

Stored size: 1.38 KB

Contents

# frozen_string_literal: true

class ViewModel
  # = View Model
  #
  # A View Model is a class that allows you to set an arbitrary hash of attributes and access all values by calling
  # attribute methods.
  #
  # ==== Examples
  #
  #   model = ViewModel.new(a: 1, b: {b1: 1, b2: 2}, c: 3)
  #
  #   model.a   # => 1
  #   model.b   # => {b1: 1, b2: 2}
  #   model.c   # => 3
  #
  # Reserved methods or attributes are left untouched. If you want to access an attribute that collides with a reserved
  # method, you can do it via the +to_hash+ method.
  #
  #   model = ViewModel.new(class: "test")
  #
  #   model.class             # => ViewModel
  #   model.to_hash[:class]   # => "test"

  def initialize(hash = {})
    hash.each do |key, value|
      instance_variable_set("@#{key}", value)
    end
  end

  def attributes
    instance_variables.map { |instance_variable| instance_variable.to_s.delete("@").to_sym }
  end

  def to_hash
    attributes.map { |attribute| {attribute => value_for(attribute)} }.inject(:merge) || {}
  end

  alias_method :to_h, :to_hash

  private

  def value_for(attribute)
    reserved_methods.include?(attribute) ? instance_variable_get("@#{attribute}") : send(attribute)
  end

  def method_missing(m, *args, &block)
    instance_variable_get("@#{m}")
  end

  def respond_to_missing?
    true
  end

  def reserved_methods
    Class.methods + Class.private_methods
  end
end

Version data entries

4 entries across 4 versions & 1 rubygems

Version Path
headmin-0.5.3 app/models/view_model.rb
headmin-0.5.2 app/models/view_model.rb
headmin-0.5.1 app/models/view_model.rb
headmin-0.5.0 app/models/view_model.rb