Class: ActiveRecord::InsertAll

Inherits:
Object
  • Object
show all
Defined in:
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.

Raises:

  • (ArgumentError)


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
# File '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)
  raise ArgumentError, "Empty list of attributes passed" if inserts.blank?

  @model, @connection, @inserts, @keys = model, model.connection, inserts, inserts.first.keys.map(&:to_s)
  @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)

  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 'lib/active_record/insert_all.rb', line 7

def connection
  @connection
end

#insertsObject (readonly)

Returns the value of attribute inserts.



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

def inserts
  @inserts
end

#keysObject (readonly)

Returns the value of attribute keys.



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

def keys
  @keys
end

#modelObject (readonly)

Returns the value of attribute model.



7
8
9
# File '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 '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 '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 '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 '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 'lib/active_record/insert_all.rb', line 8

def update_sql
  @update_sql
end

Instance Method Details

#executeObject



37
38
39
40
41
42
# File 'lib/active_record/insert_all.rb', line 37

def execute
  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 remaining this method, as it only conditionally extends keys, not always



80
81
82
83
84
85
86
# File 'lib/active_record/insert_all.rb', line 80

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



61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/active_record/insert_all.rb', line 61

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



48
49
50
# File 'lib/active_record/insert_all.rb', line 48

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

#record_timestamps?Boolean

Returns:

  • (Boolean)


75
76
77
# File 'lib/active_record/insert_all.rb', line 75

def record_timestamps?
  @record_timestamps
end

#skip_duplicates?Boolean

Returns:

  • (Boolean)


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

def skip_duplicates?
  on_duplicate == :skip
end

#updatable_columnsObject



44
45
46
# File 'lib/active_record/insert_all.rb', line 44

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

#update_duplicates?Boolean

Returns:

  • (Boolean)


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

def update_duplicates?
  on_duplicate == :update
end