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

Instance Method Summary collapse

Constructor Details

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

Returns a new instance of InsertAll.



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'activerecord/lib/active_record/insert_all.rb', line 10

def initialize(model, inserts, on_duplicate:, update_only: nil, returning: nil, unique_by: nil, record_timestamps: nil)
  @model, @connection, @inserts = model, 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

  configure_on_duplicate_update_logic

  if model.scope_attributes?
    @scope_attributes = model.scope_attributes
    @keys |= @scope_attributes.keys
  end
  @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)
  @on_duplicate = :skip if @on_duplicate == :update && updatable_columns.empty?

  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

Instance Method Details

#executeObject



43
44
45
46
47
48
49
50
# File 'activerecord/lib/active_record/insert_all.rb', line 43

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



88
89
90
91
92
93
94
# File 'activerecord/lib/active_record/insert_all.rb', line 88

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



69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'activerecord/lib/active_record/insert_all.rb', line 69

def map_key_with_value
  inserts.map do |attributes|
    attributes = attributes.stringify_keys
    attributes.merge!(scope_attributes) if 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



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

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

#record_timestamps?Boolean

Returns:

  • (Boolean)


83
84
85
# File 'activerecord/lib/active_record/insert_all.rb', line 83

def record_timestamps?
  @record_timestamps
end

#skip_duplicates?Boolean

Returns:

  • (Boolean)


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

def skip_duplicates?
  on_duplicate == :skip
end

#updatable_columnsObject



52
53
54
# File 'activerecord/lib/active_record/insert_all.rb', line 52

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

#update_duplicates?Boolean

Returns:

  • (Boolean)


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

def update_duplicates?
  on_duplicate == :update
end