@@ -12,6 +12,7 @@ def initialize(model, inserts, on_duplicate:, returning: nil, unique_by: nil)
12
12
13
13
@model , @connection , @inserts , @keys = model , model . connection , inserts , inserts . first . keys . map ( &:to_s )
14
14
@on_duplicate , @returning , @unique_by = on_duplicate , returning , unique_by
15
+ @record_timestamps = model . record_timestamps
15
16
16
17
disallow_raw_sql! ( returning )
17
18
disallow_raw_sql! ( on_duplicate )
@@ -64,15 +65,29 @@ def map_key_with_value
64
65
inserts . map do |attributes |
65
66
attributes = attributes . stringify_keys
66
67
attributes . merge! ( scope_attributes ) if scope_attributes
68
+ attributes . reverse_merge! ( timestamps_for_create ) if record_timestamps?
67
69
68
70
verify_attributes ( attributes )
69
71
70
- keys . map do |key |
72
+ keys_including_timestamps . map do |key |
71
73
yield key , attributes [ key ]
72
74
end
73
75
end
74
76
end
75
77
78
+ def record_timestamps?
79
+ @record_timestamps
80
+ end
81
+
82
+ # TODO: Consider remaining this method, as it only conditionally extends keys, not always
83
+ def keys_including_timestamps
84
+ @keys_including_timestamps ||= if record_timestamps?
85
+ keys + model . all_timestamp_attributes_in_model
86
+ else
87
+ keys
88
+ end
89
+ end
90
+
76
91
private
77
92
attr_reader :scope_attributes
78
93
@@ -134,7 +149,7 @@ def unique_by_columns
134
149
135
150
136
151
def verify_attributes ( attributes )
137
- if keys != attributes . keys . to_set
152
+ if keys_including_timestamps != attributes . keys . to_set
138
153
raise ArgumentError , "All objects being inserted must have the same keys"
139
154
end
140
155
end
@@ -148,10 +163,14 @@ def disallow_raw_sql!(value)
148
163
"by wrapping them in Arel.sql()."
149
164
end
150
165
166
+ def timestamps_for_create
167
+ model . all_timestamp_attributes_in_model . index_with ( connection . high_precision_current_timestamp )
168
+ end
169
+
151
170
class Builder # :nodoc:
152
171
attr_reader :model
153
172
154
- delegate :skip_duplicates? , :update_duplicates? , :keys , to : :insert_all
173
+ delegate :skip_duplicates? , :update_duplicates? , :keys , :keys_including_timestamps , :record_timestamps? , to : :insert_all
155
174
156
175
def initialize ( insert_all )
157
176
@insert_all , @model , @connection = insert_all , insert_all . model , insert_all . connection
@@ -162,9 +181,10 @@ def into
162
181
end
163
182
164
183
def values_list
165
- types = extract_types_from_columns_on ( model . table_name , keys : keys )
184
+ types = extract_types_from_columns_on ( model . table_name , keys : keys_including_timestamps )
166
185
167
186
values_list = insert_all . map_key_with_value do |key , value |
187
+ next value if Arel ::Nodes ::SqlLiteral === value
168
188
connection . with_yaml_fallback ( types [ key ] . serialize ( value ) )
169
189
end
170
190
@@ -196,7 +216,7 @@ def updatable_columns
196
216
end
197
217
198
218
def touch_model_timestamps_unless ( &block )
199
- return "" unless update_duplicates?
219
+ return "" unless update_duplicates? && record_timestamps?
200
220
201
221
model . timestamp_attributes_for_update_in_model . filter_map do |column_name |
202
222
if touch_timestamp_attribute? ( column_name )
@@ -219,7 +239,7 @@ def touch_timestamp_attribute?(column_name)
219
239
end
220
240
221
241
def columns_list
222
- format_columns ( insert_all . keys )
242
+ format_columns ( insert_all . keys_including_timestamps )
223
243
end
224
244
225
245
def extract_types_from_columns_on ( table_name , keys :)
0 commit comments