lib/fortnox/api/models/base.rb in fortnox-api-0.5.2 vs lib/fortnox/api/models/base.rb in fortnox-api-0.6.0
- old
+ new
@@ -1,57 +1,74 @@
-require "fortnox/api/types"
-require "ice_nine"
+# frozen_string_literal: true
+require 'fortnox/api/types'
+require 'ice_nine'
+
module Fortnox
module API
module Model
class Base < Fortnox::API::Types::Model
-
# TODO(jonas): Restructure this class a bit, it is not very readable.
- attr_accessor :unsaved, :parent
+ attr_accessor :unsaved
+ attr_writer :parent
- def self.attribute( name, *args )
- define_method( "#{ name }?" ) do
- !send( name ).nil?
+ def self.attribute(name, *args)
+ define_method("#{name}?") do
+ !send(name).nil?
end
super
end
- def self.new( hash )
+ def self.new(hash = {})
begin
- obj = preserve_meta_properties( hash ) do
- super( hash )
+ obj = preserve_meta_properties(hash) do
+ super(hash)
end
rescue Dry::Struct::Error => e
- raise Fortnox::API::AttributeError.new e
+ raise Fortnox::API::AttributeError, e
end
- IceNine.deep_freeze( obj )
+ IceNine.deep_freeze(obj)
end
+ def self.stub
+ new(self::STUB.dup)
+ end
+
+ # This filtering logic could be improved since it is currently O(N*M).
+ 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
+
def unique_id
- send( self.class::UNIQUE_ID )
+ send(self.class::UNIQUE_ID)
end
- def update( hash )
- old_attributes = self.to_hash
- new_attributes = old_attributes.merge( hash )
+ 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_attributes.delete_if { |_, value| value.nil? }
new_hash[:new] = @new
new_hash[:parent] = self
- self.class.new( new_hash )
+ self.class.new(new_hash)
end
# Generic comparison, by value, use .eql? or .equal? for object identity.
- def ==( other )
+ def ==(other)
return false unless other.is_a? self.class
- self.to_hash == other.to_hash
+ to_hash == other.to_hash
end
def new?
@new
end
@@ -59,52 +76,51 @@
def saved?
@saved
end
def parent?
- not @parent.nil?
+ !@parent.nil?
end
def parent
- @parent || self.class.new( self.class::STUB.dup )
+ @parent || self.class.new(self.class::STUB.dup)
end
- def to_hash( recursive = false )
+ 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
- private_class_method
+ private_class_method
# 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.
- def self.preserve_meta_properties( hash )
- is_unsaved = hash.delete( :unsaved ){ true }
- is_new = hash.delete( :new ){ true }
- parent = hash.delete( :parent ){ nil }
+ 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.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)
- return obj
+ obj
end
- private
+ private
def private_attributes
- @@private_attributes ||= attribute_set.select{ |a| !a.public_writer? }
+ @private_attributes ||= attribute_set.reject(&:public_writer?)
end
-
end
end
end
end