module ModelOrchestration::Base
The module containing the base functionality. This includes class methods to specify nested models and dependencies, as well as ActiveModel-like functionality, such as attribute accessors for the nested models and validation methods.
Public Class Methods
Instantiate the model and all nested models. Attributes can be submitted as a hash and will be handed over to the nested models.
# File lib/model_orchestration/base.rb, line 119 def initialize(attrs = {}) @nested_model_instances = {} self._nested_models.each do |model| model_class = model.to_s.classify.constantize if attrs.include?(model) @nested_model_instances[model] = initialize_nested_model(model_class, attrs[model]) else @nested_model_instances[model] = initialize_nested_model(model_class) end end self._dependencies.each do |from, tos| tos.each do |to| @nested_model_instances[from].public_send("#{to.to_s}=", @nested_model_instances[to]) end end end
Public Instance Methods
Get a nested model by name (symbol).
class Signup include ModelOrchestration::Base nested_model :company nested_model :employee nested_model_dependency from: :employee, to: :company end signup = Signup.new company = signup[:company]
Because ActiveRecord classes also support the +[]+ method, it can be chained to get attributes of nested models.
company_name = signup[:company][:name]
# File lib/model_orchestration/base.rb, line 159 def [](key) send key end
Set a nested model by name (symbol).
class Signup include ModelOrchestration::Base nested_model :company nested_model :employee nested_model_dependency from: :employee, to: :company end signup = Signup.new signup[:company] = Company.new
# File lib/model_orchestration/base.rb, line 177 def []=(key, value) send "#{key}=", value end
See: api.rubyonrails.org/classes/ActiveModel/Validations.html#method-i-invalid-3F
# File lib/model_orchestration/base.rb, line 217 def invalid?(context = nil) !valid?(context) end
Implements attribute accessor methods for nested models.
# File lib/model_orchestration/base.rb, line 183 def method_missing(message, *args, &block) if @nested_model_instances.include?(message) # Get nested model accessor @nested_model_instances[message] elsif message =~ /^([^=]+)=$/ # Set nested model accessor attr = message.to_s.chop.to_sym if @nested_model_instances.include?(attr) @nested_model_instances[attr] = args.first else super end else super end end
See: api.rubyonrails.org/classes/ActiveModel/Validations.html#method-i-valid-3F
# File lib/model_orchestration/base.rb, line 202 def valid?(context = nil) valid = true @nested_model_instances.each do |key, instance| valid = false unless instance.valid?(context) end valid end
See: api.rubyonrails.org/classes/ActiveModel/Validations.html#method-i-validate-21
# File lib/model_orchestration/base.rb, line 223 def validate!(context = nil) valid?(context) || raise_validation_error end
Protected Instance Methods
# File lib/model_orchestration/base.rb, line 233 def initialize_nested_model(model_class, hash_or_instance = {}) if hash_or_instance.is_a? Hash model_class.new(hash_or_instance) elsif hash_or_instance.is_a? model_class hash_or_instance else raise(TypeError, "hash_or_instance must be of type #{model_class.to_s}") end end
# File lib/model_orchestration/base.rb, line 229 def raise_validation_error raise(ValidationError.new(self)) end