@@ -171,6 +171,71 @@ defmodule AshPostgres.BulkCreateTest do
171
171
end )
172
172
end
173
173
174
+ @ tag :focus
175
+ test "bulk upsert returns skipped records with return_skipped_upsert?" do
176
+ assert [
177
+ { :ok , % { title: "fredfoo" , uniq_if_contains_foo: "1foo" , price: 10 } } ,
178
+ { :ok , % { title: "georgefoo" , uniq_if_contains_foo: "2foo" , price: 20 } } ,
179
+ { :ok , % { title: "herbert" , uniq_if_contains_foo: "3" , price: 30 } }
180
+ ] =
181
+ Ash . bulk_create! (
182
+ [
183
+ % { title: "fredfoo" , uniq_if_contains_foo: "1foo" , price: 10 } ,
184
+ % { title: "georgefoo" , uniq_if_contains_foo: "2foo" , price: 20 } ,
185
+ % { title: "herbert" , uniq_if_contains_foo: "3" , price: 30 }
186
+ ] ,
187
+ Post ,
188
+ :create ,
189
+ return_stream?: true ,
190
+ return_records?: true
191
+ )
192
+ |> Enum . sort_by ( fn { :ok , result } -> result . title end )
193
+
194
+ results =
195
+ Ash . bulk_create! (
196
+ [
197
+ % { title: "fredfoo" , uniq_if_contains_foo: "1foo" , price: 10 } ,
198
+ % { title: "georgefoo" , uniq_if_contains_foo: "2foo" , price: 20_000 } ,
199
+ % { title: "herbert" , uniq_if_contains_foo: "3" , price: 30 }
200
+ ] ,
201
+ Post ,
202
+ :upsert_with_no_filter ,
203
+ return_stream?: true ,
204
+ upsert_condition: expr ( price != upsert_conflict ( :price ) ) ,
205
+ return_errors?: true ,
206
+ return_records?: true ,
207
+ return_skipped_upsert?: true
208
+ )
209
+ |> Enum . sort_by ( fn
210
+ { :ok , result } ->
211
+ result . title
212
+
213
+ _ ->
214
+ nil
215
+ end )
216
+
217
+ assert [
218
+ { :ok , skipped } ,
219
+ { :ok , updated } ,
220
+ { :ok , no_conflict }
221
+ ] = results
222
+
223
+ # "fredfoo" was skipped because price matches (10 == 10)
224
+ assert skipped . title == "fredfoo"
225
+ assert skipped . price == 10
226
+ assert Ash.Resource . get_metadata ( skipped , :upsert_skipped ) == true
227
+
228
+ # "georgefoo" was updated because price differs (20 -> 20_000)
229
+ assert updated . title == "georgefoo"
230
+ assert updated . price == 20_000
231
+ refute Ash.Resource . get_metadata ( updated , :upsert_skipped )
232
+
233
+ # "herbert" had no conflict (doesn't match identity)
234
+ assert no_conflict . title == "herbert"
235
+ assert no_conflict . price == 30
236
+ refute Ash.Resource . get_metadata ( no_conflict , :upsert_skipped )
237
+ end
238
+
174
239
# confirmed that this doesn't work because it can't. An upsert must map to a potentially successful insert.
175
240
# leaving this test here for posterity
176
241
# test "bulk creates can upsert with id" do
0 commit comments