class Pakyow::Data::Container
@api private
Attributes
connection[R]
sources[R]
Public Class Methods
new(connection:, sources:, objects:)
click to toggle source
# File lib/pakyow/data/container.rb, line 13 def initialize(connection:, sources:, objects:) @connection, @sources = connection, sources @object_map = objects.each_with_object({}) { |object, map| map[object.__object_name.name] = object } end
Public Instance Methods
finalize_associations!(other_containers)
click to toggle source
# File lib/pakyow/data/container.rb, line 38 def finalize_associations!(other_containers) @sources.each do |source| discover_has_and_belongs_to!(source, other_containers) end @sources.each do |source| set_container_for_source!(source) define_reciprocal_associations!(source, other_containers) end end
finalize_sources!(other_containers)
click to toggle source
# File lib/pakyow/data/container.rb, line 49 def finalize_sources!(other_containers) @sources.each do |source| mixin_commands!(source) mixin_dataset_methods!(source) define_attributes_for_associations!(source, other_containers) define_queries_for_attributes!(source) wrap_defined_queries!(source) define_methods_for_associations!(source) define_methods_for_objects!(source) finalize_source_types!(source) end end
object(object_name)
click to toggle source
# File lib/pakyow/data/container.rb, line 34 def object(object_name) @object_map.fetch(object_name, Object) end
source(source_name)
click to toggle source
# File lib/pakyow/data/container.rb, line 21 def source(source_name) plural_source_name = Support.inflector.pluralize(source_name).to_sym if found_source = sources.find { |source| source.plural_name == plural_source_name } found_source.new( @connection.dataset_for_source(found_source) ) end end
Private Instance Methods
adapter()
click to toggle source
# File lib/pakyow/data/container.rb, line 64 def adapter @connection.adapter end
define_attributes_for_associations!(source, other_containers)
click to toggle source
# File lib/pakyow/data/container.rb, line 125 def define_attributes_for_associations!(source, other_containers) source.associations.values.flatten.each do |association| associated_source = (@sources + other_containers.flat_map(&:sources)).find { |potentially_associated_source| potentially_associated_source.plural_name == association.associated_source_name } if associated_source association.associated_source = associated_source if association.type == :through association.joining_source = (@sources + other_containers.flat_map(&:sources)).find { |potentially_joining_source| potentially_joining_source.plural_name == association.joining_source_name } end if association.type == :belongs # Define an attribute for the foreign key. # source.attribute( association.foreign_key_field, association.foreign_key_type, foreign_key: association.associated_source_name ) end end end end
define_methods_for_associations!(source)
click to toggle source
# File lib/pakyow/data/container.rb, line 210 def define_methods_for_associations!(source) source.associations.values.flatten.each do |association| method_name = :"with_#{association.name}" unless source.instance_methods.include?(method_name) source.class_eval do define_method method_name do including(association.name) end end end end end
define_methods_for_objects!(source)
click to toggle source
# File lib/pakyow/data/container.rb, line 223 def define_methods_for_objects!(source) @object_map.keys.each do |object_name| method_name = :"as_#{object_name}" unless source.instance_methods.include?(method_name) source.class_eval do define_method method_name do as(object_name) end end end end end
define_queries_for_attributes!(source)
click to toggle source
# File lib/pakyow/data/container.rb, line 193 def define_queries_for_attributes!(source) source.attributes.keys.each do |attribute| method_name = :"by_#{attribute}" unless source.instance_methods.include?(method_name) source.class_eval do define_method method_name do |value| self.class.container.connection.adapter.result_for_attribute_value(attribute, value, self) end # Qualify the query. # subscribe :"by_#{attribute}", attribute => :__arg0__ end end end end
define_reciprocal_associations!(source, other_containers)
click to toggle source
# File lib/pakyow/data/container.rb, line 153 def define_reciprocal_associations!(source, other_containers) (source.associations[:has_many] + source.associations[:has_one]).each do |association| associated_source = (@sources + other_containers.flat_map(&:sources)).find { |potentially_associated_source| potentially_associated_source.plural_name == association.associated_source_name } if associated_source if association.type == :through joining_source = (@sources + other_containers.flat_map(&:sources)).find { |potential_joining_source| potential_joining_source.plural_name == association.joining_source_name } if joining_source unless joining_source.associations[:belongs_to].any? { |current_association| current_association.name == association.left_name } joining_source.belongs_to(association.left_name, source: associated_source.plural_name) end unless joining_source.associations[:belongs_to].any? { |current_association| current_association.name == association.right_name } joining_source.belongs_to(association.right_name, source: source.plural_name) end unless association.internal? unless associated_source.associations[association.specific_type].any? { |current_association| current_association.type == :through && current_association.joining_source_name == association.joining_source_name } associated_source.send(association.specific_type, association.associated_name, source: source.plural_name, as: association.left_name, through: association.joining_source_name, dependent: association.dependent) end unless source.associations[association.specific_type].any? { |current_association| current_association.type == :through && current_association.associated_source_name == association.joining_source_name } source.send(association.specific_type, association.joining_source_name, source: joining_source.plural_name, as: Support.inflector.singularize(association.associated_name), dependent: association.dependent) end end end else unless associated_source.associations[:belongs_to].any? { |current_association| current_association.name == Support.inflector.singularize(association.associated_name).to_sym } associated_source.belongs_to(association.associated_name, source: source.plural_name) end end end end end
discover_has_and_belongs_to!(source, other_containers)
click to toggle source
# File lib/pakyow/data/container.rb, line 68 def discover_has_and_belongs_to!(source, other_containers) source.associations.values.flatten.select { |association| # Only look for has_* associations that aren't already setup through another source. # association.type == :has }.each do |association| reciprocal_association = nil reciprocal_source = (@sources + other_containers.flat_map(&:sources)).reject { |potentially_reciprocal_source| potentially_reciprocal_source == source }.find { |potentially_reciprocal_source| reciprocal_association = potentially_reciprocal_source.associations.values.flatten.find { |potentially_reciprocal_association| potentially_reciprocal_association.specific_type == association.specific_type && potentially_reciprocal_association.associated_source_name == source.plural_name && Support.inflector.pluralize(potentially_reciprocal_association.name) == Support.inflector.pluralize(association.associated_name) && Support.inflector.pluralize(potentially_reciprocal_association.associated_name) == Support.inflector.pluralize(association.name) } } if reciprocal_source joining_source_name = [source.plural_name, reciprocal_source.plural_name].sort.join("_") joining_source = (@sources + other_containers.flat_map(&:sources)).find { |potentially_joining_source| potentially_joining_source.plural_name == joining_source_name } unless joining_source joining_source = source.ancestors.find { |ancestor| ancestor != source && ancestor.ancestors.include?(Sources::Base) }.make( joining_source_name, adapter: source.adapter, connection: source.connection, within: source.__object_name.namespace ) @sources << joining_source end # Modify both sides of the association to be through the joining source. # source.setup_as_through(association, through: joining_source_name).internal! reciprocal_source.setup_as_through(reciprocal_association, through: joining_source_name).internal! end end end
finalize_source_types!(source)
click to toggle source
# File lib/pakyow/data/container.rb, line 259 def finalize_source_types!(source) source.attributes.each do |attribute_name, attribute_info| if attribute_info.is_a?(Hash) type = Types.type_for(attribute_info[:type], connection.types) if attribute_name == source.primary_key_field type = type.meta(primary_key: true) end source.attributes[attribute_name] = type.meta(attribute_info[:options]) end end end
mixin_commands!(source)
click to toggle source
# File lib/pakyow/data/container.rb, line 117 def mixin_commands!(source) source.include adapter.class.const_get("Commands") end
mixin_dataset_methods!(source)
click to toggle source
# File lib/pakyow/data/container.rb, line 121 def mixin_dataset_methods!(source) source.extend adapter.class.const_get("DatasetMethods") end
set_container_for_source!(source)
click to toggle source
# File lib/pakyow/data/container.rb, line 113 def set_container_for_source!(source) source.container = self end
wrap_defined_queries!(source)
click to toggle source
Override queries with methods that update the source with a new dataset.
Calls superclass method
# File lib/pakyow/data/container.rb, line 238 def wrap_defined_queries!(source) local_queries = source.queries source.prepend( Module.new do local_queries.each do |query| define_method query do |*args, &block| tap do result = super(*args, &block) case result when self.class result else __setobj__(result) end end end end end ) end