class Babik::QuerySet::SelectRelated

Delegate object that must deals with all the select_related particularities.

Attributes

associations[R]
model[R]

Public Class Methods

new(model, selection_paths) click to toggle source

Creates a new SelectRelated

# File lib/babik/queryset/components/select_related.rb, line 14
def initialize(model, selection_paths)
  @model = model
  @associations = []
  selection_paths = [selection_paths] if selection_paths.class != Array
  selection_paths.each do |selection_path|
    @associations << Babik::Selection::SelectRelatedSelection.new(@model, selection_path)
  end
end

Public Instance Methods

left_joins_by_alias() click to toggle source

Return the joins that are needed according to the associated path @return [Hash{table_alias: String}] Left joins by table alias.

# File lib/babik/queryset/components/select_related.rb, line 25
def left_joins_by_alias
  left_joins_by_alias = {}
  @associations.each do |association|
    left_joins_by_alias.merge!(association.left_joins_by_alias)
  end
  left_joins_by_alias
end

Private Instance Methods

instantiate_associated_object(record, association) click to toggle source

Construct an associated object

# File lib/babik/queryset/components/select_related.rb, line 60
def instantiate_associated_object(record, association)
  target_model = association.target_model
  target_object = target_model.new

  # First, get the attributes that have the desired prefix (the association path)
  target_attributes_with_prefix = record.select { |attr, value| attr.start_with?("#{association.id}__") }

  # Second, convert it to a hash
  target_attributes = (target_attributes_with_prefix.map do |attribute, value|
    [attribute.split('__')[1], value]
  end).to_h

  # Last, assign it to the associated object
  target_object.assign_attributes(target_attributes)
  target_object
end
instantiate_model_object(record) click to toggle source

Construct a model object

# File lib/babik/queryset/components/select_related.rb, line 53
def instantiate_model_object(record)
  object = @model.new
  object.assign_attributes(record.select { |attribute| @model.column_names.include?(attribute) })
  object
end