Class: ActiveRecord::InsertAll

Inherits:
Object
  • Object
show all
Defined in:
activerecord/lib/active_record/insert_all.rb

Overview

:nodoc:

Defined Under Namespace

Classes: Builder

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(relation, connection, inserts, on_duplicate:, update_only: nil, returning: nil, unique_by: nil, record_timestamps: nil) ⇒ InsertAll



18
19
20
21
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
# File 'activerecord/lib/active_record/insert_all.rb', line 18

def initialize(relation, connection, inserts, on_duplicate:, update_only: nil, returning: nil, unique_by: nil, record_timestamps: nil)
  @relation = relation
  @model, @connection, @inserts = relation.model, connection, inserts.map(&:stringify_keys)
  @on_duplicate, @update_only, @returning, @unique_by = on_duplicate, update_only, returning, unique_by
  @record_timestamps = record_timestamps.nil? ? model.record_timestamps : record_timestamps

  disallow_raw_sql!(on_duplicate)
  disallow_raw_sql!(returning)

  if @inserts.empty?
    @keys = []
  else
    resolve_sti
    resolve_attribute_aliases
    @keys = @inserts.first.keys
  end

  @scope_attributes = relation.scope_for_create.except(@model.inheritance_column)
  @keys |= @scope_attributes.keys
  @keys = @keys.to_set

  @returning = (connection.supports_insert_returning? ? primary_keys : false) if @returning.nil?
  @returning = false if @returning == []

  @unique_by = find_unique_index_for(@unique_by)

  configure_on_duplicate_update_logic
  ensure_valid_options_for_connection!
end

Instance Attribute Details

#connectionObject (readonly)

Returns the value of attribute connection.



7
8
9
# File 'activerecord/lib/active_record/insert_all.rb', line 7

def connection
  @connection
end

#insertsObject (readonly)

Returns the value of attribute inserts.



7
8
9
# File 'activerecord/lib/active_record/insert_all.rb', line 7

def inserts
  @inserts
end

#keysObject (readonly)

Returns the value of attribute keys.



7
8
9
# File 'activerecord/lib/active_record/insert_all.rb', line 7

def keys
  @keys
end

#modelObject (readonly)

Returns the value of attribute model.



7
8
9
# File 'activerecord/lib/active_record/insert_all.rb', line 7

def model
  @model
end

#on_duplicateObject (readonly)

Returns the value of attribute on_duplicate.



8
9
10
# File 'activerecord/lib/active_record/insert_all.rb', line 8

def on_duplicate
  @on_duplicate
end

#returningObject (readonly)

Returns the value of attribute returning.



8
9
10
# File 'activerecord/lib/active_record/insert_all.rb', line 8

def returning
  @returning
end

#unique_byObject (readonly)

Returns the value of attribute unique_by.



8
9
10
# File 'activerecord/lib/active_record/insert_all.rb', line 8

def unique_by
  @unique_by
end

#update_onlyObject (readonly)

Returns the value of attribute update_only.



8
9
10
# File 'activerecord/lib/active_record/insert_all.rb', line 8

def update_only
  @update_only
end

#update_sqlObject (readonly)

Returns the value of attribute update_sql.



8
9
10
# File 'activerecord/lib/active_record/insert_all.rb', line 8

def update_sql
  @update_sql
end

Class Method Details

.execute(relation) ⇒ Object



11
12
13
14
15
# File 'activerecord/lib/active_record/insert_all.rb', line 11

def execute(relation, ...)
  relation.model.with_connection do |c|
    new(relation, c, ...).execute
  end
end

Instance Method Details

#executeObject



48
49
50
51
52
53
54
55
# File 'activerecord/lib/active_record/insert_all.rb', line 48

def execute
  return ActiveRecord::Result.empty if inserts.empty?

  message = +"#{model} "
  message << "Bulk " if inserts.many?
  message << (on_duplicate == :update ? "Upsert" : "Insert")
  connection.exec_insert_all to_sql, message
end

#keys_including_timestampsObject

TODO: Consider renaming this method, as it only conditionally extends keys, not always



92
93
94
95
96
97
98
# File 'activerecord/lib/active_record/insert_all.rb', line 92

def keys_including_timestamps
  @keys_including_timestamps ||= if record_timestamps?
    keys + model.all_timestamp_attributes_in_model
  else
    keys
  end
end

#map_key_with_valueObject



73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'activerecord/lib/active_record/insert_all.rb', line 73

def map_key_with_value
  inserts.map do |attributes|
    attributes = attributes.stringify_keys
    attributes.merge!(@scope_attributes)
    attributes.reverse_merge!(timestamps_for_create) if record_timestamps?

    verify_attributes(attributes)

    keys_including_timestamps.map do |key|
      yield key, attributes[key]
    end
  end
end

#primary_keysObject



61
62
63
# File 'activerecord/lib/active_record/insert_all.rb', line 61

def primary_keys
  Array(@model.schema_cache.primary_keys(model.table_name))
end

#record_timestamps?Boolean



87
88
89
# File 'activerecord/lib/active_record/insert_all.rb', line 87

def record_timestamps?
  @record_timestamps
end

#skip_duplicates?Boolean



65
66
67
# File 'activerecord/lib/active_record/insert_all.rb', line 65

def skip_duplicates?
  on_duplicate == :skip
end

#updatable_columnsObject



57
58
59
# File 'activerecord/lib/active_record/insert_all.rb', line 57

def updatable_columns
  @updatable_columns ||= keys - readonly_columns - unique_by_columns
end

#update_duplicates?Boolean



69
70
71
# File 'activerecord/lib/active_record/insert_all.rb', line 69

def update_duplicates?
  on_duplicate == :update
end