class Fortnox::API::Model::Base

Attributes

parent[W]
unsaved[RW]

TODO(jonas): Restructure this class a bit, it is not very readable.

Public Class Methods

attribute(name, *args) click to toggle source
Calls superclass method
# File lib/fortnox/api/models/base.rb, line 15
def self.attribute(name, *args)
  define_method("#{name}?") do
    !send(name).nil?
  end

  super
end
new(hash = {}) click to toggle source
Calls superclass method Fortnox::API::Types::Model::new
# File lib/fortnox/api/models/base.rb, line 23
def self.new(hash = {})
  begin
    obj = preserve_meta_properties(hash) do
      super(hash)
    end
  rescue Dry::Struct::Error => e
    raise Fortnox::API::AttributeError, e
  end

  IceNine.deep_freeze(obj)
end
stub() click to toggle source
# File lib/fortnox/api/models/base.rb, line 35
def self.stub
  new(self::STUB.dup)
end

Private Class Methods

preserve_meta_properties(hash) { || ... } click to toggle source

dry-types filter anything that isn't specified as an attribute on the class that is being instantiated. This wrapper preserves the meta properties we need to track object state during that initilisation and sets them on the object after dry-types is done with it.

# File lib/fortnox/api/models/base.rb, line 102
def self.preserve_meta_properties(hash)
  is_unsaved = hash.delete(:unsaved) { true }
  is_new = hash.delete(:new) { true }
  parent = hash.delete(:parent) { nil }

  obj = yield

  # TODO: remove new, unsaved, saved
  obj.instance_variable_set(:@unsaved, is_unsaved)
  obj.instance_variable_set(:@saved, !is_unsaved)
  obj.instance_variable_set(:@new, is_new)
  obj.instance_variable_set(:@parent, parent)

  obj
end

Public Instance Methods

==(other) click to toggle source

Generic comparison, by value, use .eql? or .equal? for object identity.

# File lib/fortnox/api/models/base.rb, line 67
def ==(other)
  return false unless other.is_a? self.class
  to_hash == other.to_hash
end
attributes(*options) click to toggle source

This filtering logic could be improved since it is currently O(N*M).

# File lib/fortnox/api/models/base.rb, line 40
def attributes(*options)
  return self.class.schema if options.nil?

  options = Array(options)

  self.class.schema.find_all do |_name, attribute|
    options.all? { |option| attribute.is?(option) }
  end
end
new?() click to toggle source
# File lib/fortnox/api/models/base.rb, line 72
def new?
  @new
end
parent() click to toggle source
# File lib/fortnox/api/models/base.rb, line 84
def parent
  @parent || self.class.new(self.class::STUB.dup)
end
parent?() click to toggle source
# File lib/fortnox/api/models/base.rb, line 80
def parent?
  !@parent.nil?
end
saved?() click to toggle source
# File lib/fortnox/api/models/base.rb, line 76
def saved?
  @saved
end
to_hash(recursive = false) click to toggle source
Calls superclass method
# File lib/fortnox/api/models/base.rb, line 88
def to_hash(recursive = false)
  return super() if recursive

  self.class.schema.keys.each_with_object({}) do |key, result|
    result[key] = self[key]
  end
end
unique_id() click to toggle source
# File lib/fortnox/api/models/base.rb, line 50
def unique_id
  send(self.class::UNIQUE_ID)
end
update(hash) click to toggle source
# File lib/fortnox/api/models/base.rb, line 54
def update(hash)
  old_attributes = to_hash
  new_attributes = old_attributes.merge(hash)

  return self if new_attributes == old_attributes

  new_hash = new_attributes.delete_if { |_, value| value.nil? }
  new_hash[:new] = @new
  new_hash[:parent] = self
  self.class.new(new_hash)
end

Private Instance Methods

private_attributes() click to toggle source
# File lib/fortnox/api/models/base.rb, line 120
def private_attributes
  @private_attributes ||= attribute_set.reject(&:public_writer?)
end