Module: ActiveRecord::SpawnMethods

Defined in:
lib/referrable_joins/active_record_hacks.rb

Instance Method Summary collapse

Instance Method Details

#merge(r) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/referrable_joins/active_record_hacks.rb', line 22

def merge(r)
  merged_relation = clone
  return merged_relation unless r
  return to_a & r if r.is_a?(Array)

  Relation::ASSOCIATION_METHODS.each do |method|
    value = r.send(:"#{method}_values")

    unless value.empty?
      if method == :includes
        merged_relation = merged_relation.includes(value)
      else
        merged_relation.send(:"#{method}_values=", value)
      end
    end
  end

  (Relation::MULTI_VALUE_METHODS - [:joins, :where, :order]).each do |method|
    value = r.send(:"#{method}_values")
    merged_relation.send(:"#{method}_values=", merged_relation.send(:"#{method}_values") + value) if value.present?
  end

  order_value = r.order_values
  if order_value.present?
    if r.reorder_flag
      merged_relation.order_values = order_value
    else
      merged_relation.order_values = merged_relation.order_values + order_value
    end
  end
  
  # MONKEYPATCH Only change, right here.
  merged_relation = merged_relation.outer_joins(r.outer_joins_values).inner_joins(r.inner_joins_values)

  merged_wheres = @where_values + r.where_values

  unless @where_values.empty?
    # Remove duplicates, last one wins.
    seen = Hash.new { |h,table| h[table] = {} }
    merged_wheres = merged_wheres.reverse.reject { |w|
      nuke = false
      if w.respond_to?(:operator) && w.operator == :==
        name              = w.left.name
        table             = w.left.relation.name
        nuke              = seen[table][name]
        seen[table][name] = true
      end
      nuke
    }.reverse
  end

  merged_relation.where_values = merged_wheres

  Relation::SINGLE_VALUE_METHODS.reject {|m| m == :lock}.each do |method|
    value = r.send(:"#{method}_value")
    merged_relation.send(:"#{method}_value=", value) unless value.nil?
  end

  merged_relation.lock_value = r.lock_value unless merged_relation.lock_value

  # Apply scope extension modules
  merged_relation.send :apply_modules, r.extensions

  merged_relation
end