lib/wolf_core/domain/domain_object.rb
# frozen_string_literal: true module WolfCore class DomainObject include ActiveModel::Model include ActiveModel::Dirty include ActiveModel::Callbacks define_model_callbacks :initialize, only: [:after, :before] define_model_callbacks :validation, only: [:after, :before] define_model_callbacks :attribute_change, only: [:after, :before] after_initialize do parse_attributes end after_attribute_change do parse_attributes end class_attribute :fields, default: [] def self.define_attributes(*attributes) self.fields += attributes attr_accessor(*attributes) define_attribute_methods(*attributes) attributes.each do |attribute| define_method(:"#{attribute}=") do |value| send(:"#{attribute}_will_change!") unless value == send(attribute) run_callbacks :attribute_change do instance_variable_set(:"@#{attribute}", value) end value end end end def self.cast_all(objects) objects.map { |object| cast(object) } end def self.cast(object) if object.is_a?(self) object else result = self.create(object) success_key = extract_success_key result.success? ? result.data.send(success_key) : object end end def self.create_all(objects) success_key = extract_success_key final_array = [] objects.each do |object| result = create(object) if result.failure? return result else final_array << result.data[success_key.to_sym] end end Result.success(data: { success_key.pluralize.to_s => final_array }) end def self.create(params = {}, **kwargs) object = self.new(parse_params(params, **kwargs)) object.reset_changes if object.valid? success_key = extract_success_key Result.success(data: { success_key => object }) else Result.failure(error: { message: object.errors.full_messages.to_sentence }) end rescue ActiveModel::UnknownAttributeError => e Result.failure(error: { message: e.message, error_type: e.class.to_s }) end def self.extract_success_key self.to_s.split('::').last.underscore end def self.parse_params(params = {}, **kwargs) params = {} unless params.is_a?(Hash) params = params.merge(kwargs) (params.to_h).with_indifferent_access end def initialize(attributes = {}) run_callbacks :initialize do super end end def valid?(*args) run_callbacks(:validation) do super end errors.empty? end def attributes instance_values.slice(*self.class.fields.map(&:to_s)).with_indifferent_access end def attributes=(attrs) run_callbacks :attribute_change do super end end def reset_changes self.changes_applied end def parse_attributes; end end end