Sha256: 411ea0b505bb0f1383e56c5967c6e1cfb3c42b389c6e5915f1ec33f91b0d7129

Contents?: true

Size: 1.76 KB

Versions: 1

Compression:

Stored size: 1.76 KB

Contents

# frozen_string_literal: true

require_relative 'immutable_object'
require_relative 'model_schema'

module Upgrow
  # Base class for Models. As an Immutable Object, it sets a default schema with
  # the minimal attribute ID, as well as requires all attributes to be set upon
  # initialization.
  class BasicModel < ImmutableObject
    class AssociationNotLoadedError < StandardError; end

    class << self
      # Defines an association in the Model Schema.
      #
      # @param name [Symbol] the name of the association.
      def belongs_to(name)
        schema.association(name)
      end

      # Defines an association in the Model Schema.
      #
      # @param name [Symbol] the name of the association.
      def has_many(name)
        schema.association(name)
      end
    end

    self.schema = ModelSchema.new

    attribute :id

    attr_reader :associations

    # Initializes a new Model with the given member values.
    #
    # @param args [Hash<Symbol, Object>] the list of values for each attribute
    #   and association.
    #
    # @raise [KeyError] if an attribute is missing in the list of arguments.
    def initialize(**args)
      @associations = self.class.schema.association_names.to_h do |name|
        [name, args[name]]
      end.freeze

      attributes = self.class.schema.attribute_names.to_h do |name|
        [name, args.fetch(name)]
      end

      super(**attributes)
    end

    private

    def method_missing(name, *args, &block)
      return super unless associations.include?(name)

      associations[name] || raise(
        AssociationNotLoadedError,
        "Association #{name} not loaded for #{self.class.name}."
      )
    end

    def respond_to_missing?(name, _include_private = false)
      associations.include?(name) || super
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
upgrow-0.0.4 lib/upgrow/basic_model.rb