class SelfishAssociations::AssociationTraverser
Public Class Methods
new(klass)
click to toggle source
# File lib/selfish_associations/utils/association_traverser.rb, line 38 def initialize(klass) klass.is_a?(::Class) or ::Kernel.raise ::ArgumentError, "Input must be a Class" @original = klass @associations = [] reset! end
Public Instance Methods
associations!(merge: true)
click to toggle source
Return associations traversed Default behavior is to return an array of each path (Array of associations) Use argument merge = true to return a Hash where duplicate keys are merged
# File lib/selfish_associations/utils/association_traverser.rb, line 53 def associations!(merge: true) merge ? PathMerger.new(@associations).merge : @associations end
method_missing(method, *args)
click to toggle source
Method Missing pattern (reluctantly). Really we could initialize a new at each node and pre-define all methods But this actually seems more lightweight.
# File lib/selfish_associations/utils/association_traverser.rb, line 85 def method_missing(method, *args) send(method, *args) end
reset!()
click to toggle source
# File lib/selfish_associations/utils/association_traverser.rb, line 45 def reset! @path = [] @klass = @original end
send(method, *args)
click to toggle source
Check if method is an association or a column If Association
, store current node and iterate to the association. If it is a column, return an Arel::Node representing that value Else, raise NoMethodError
# File lib/selfish_associations/utils/association_traverser.rb, line 61 def send(method, *args) if @klass.column_names.include?(method.to_s) @associations << @path if @path.present? node = @klass.arel_table[method] reset! return node elsif @klass.reflect_on_association(method) @path << method @klass = @klass.reflect_on_association(method).klass return self elsif @klass.selfish_associations[method].present? @path << method @klass = @klass.selfish_associations[method].foreign_class return self else message = "No association or field named #{method} found for class #{@klass}" reset! ::Kernel.raise ::NoMethodError, message end end