123456789_123456789_123456789_123456789_123456789_

Class: ActiveRecord::Relation::Merger

Do not use. This class is for internal use only.
Relationships & Source Files
Inherits: Object
Defined in: activerecord/lib/active_record/relation/merger.rb

Constant Summary

Class Method Summary

Instance Attribute Summary

Instance Method Summary

Constructor Details

.new(relation, other) ⇒ Merger

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/merger.rb', line 46

def initialize(relation, other)
  @relation = relation
  @values   = other.values
  @other    = other
end

Instance Attribute Details

#other (readonly)

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/merger.rb', line 44

attr_reader :relation, :values, :other

#relation (readonly)

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/merger.rb', line 44

attr_reader :relation, :values, :other

#replace_from_clause?Boolean (readonly, private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/merger.rb', line 186

def replace_from_clause?
  relation.from_clause.empty? && !other.from_clause.empty? &&
    relation.model.base_class == other.model.base_class
end

#values (readonly)

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/merger.rb', line 44

attr_reader :relation, :values, :other

Instance Method Details

#merge

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/merger.rb', line 58

def merge
  NORMAL_VALUES.each do |name|
    value = values[name]
    # The unless clause is here mostly for performance reasons (since the `send` call might be moderately
    # expensive), most of the time the value is going to be `nil` or `.blank?`, the only catch is that
    # `false.blank?` returns `true`, so there needs to be an extra check so that explicit `false` values
    # don't fall through the cracks.
    unless value.nil? || (value.blank? && false != value)
      relation.public_send(:"#{name}!", *value)
    end
  end

  relation.none! if other.null_relation?

  merge_select_values
  merge_multi_values
  merge_single_values
  merge_clauses
  merge_preloads
  merge_joins
  merge_outer_joins

  relation
end

#merge_clauses (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/merger.rb', line 176

def merge_clauses
  relation.from_clause = other.from_clause if replace_from_clause?

  where_clause = relation.where_clause.merge(other.where_clause)
  relation.where_clause = where_clause unless where_clause.empty?

  having_clause = relation.having_clause.merge(other.having_clause)
  relation.having_clause = having_clause unless having_clause.empty?
end

#merge_joins (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/merger.rb', line 117

def merge_joins
  return if other.joins_values.empty?

  if other.model == relation.model
    relation.joins_values |= other.joins_values
  else
    associations, others = other.joins_values.partition do |join|
      case join
      when Hash, Symbol, Array; true
      end
    end

    join_dependency = other.construct_join_dependency(
      associations, Arel::Nodes::InnerJoin
    )
    relation.joins!(join_dependency, *others)
  end
end

#merge_multi_values (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/merger.rb', line 155

def merge_multi_values
  if other.reordering_value
    # override any order specified in the original relation
    relation.reorder!(*other.order_values)
  elsif other.order_values.any?
    # merge in order_values from relation
    relation.order!(*other.order_values)
  end

  extensions = other.extensions - relation.extensions
  relation.extending!(*extensions) if extensions.any?
end

#merge_outer_joins (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/merger.rb', line 136

def merge_outer_joins
  return if other.left_outer_joins_values.empty?

  if other.model == relation.model
    relation.left_outer_joins_values |= other.left_outer_joins_values
  else
    associations, others = other.left_outer_joins_values.partition do |join|
      case join
      when Hash, Symbol, Array; true
      end
    end

    join_dependency = other.construct_join_dependency(
      associations, Arel::Nodes::OuterJoin
    )
    relation.left_outer_joins!(join_dependency, *others)
  end
end

#merge_preloads (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/merger.rb', line 96

def merge_preloads
  return if other.preload_values.empty? && other.includes_values.empty?

  if other.model == relation.model
    relation.preload_values |= other.preload_values unless other.preload_values.empty?
    relation.includes_values |= other.includes_values unless other.includes_values.empty?
  else
    reflection = relation.model.reflect_on_all_associations.find do |r|
      r.class_name == other.model.name
    end || return

    unless other.preload_values.empty?
      relation.preload! reflection.name => other.preload_values
    end

    unless other.includes_values.empty?
      relation.includes! reflection.name => other.includes_values
    end
  end
end

#merge_select_values (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/merger.rb', line 84

def merge_select_values
  return if other.select_values.empty?

  if other.model == relation.model
    relation.select_values |= other.select_values
  else
    relation.select_values |= other.instance_eval do
      arel_columns(select_values)
    end
  end
end

#merge_single_values (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/relation/merger.rb', line 168

def merge_single_values
  relation.lock_value ||= other.lock_value if other.lock_value

  unless other.create_with_value.blank?
    relation.create_with_value = (relation.create_with_value || {}).merge(other.create_with_value)
  end
end