Skip to content

Conversation

allen-moonshot
Copy link

Explain your user case and expected results

with a valid record at age 19, i would expect adding 1 to return 20 into the resultant struct with

DB.Where("name = ?", "jinzhu").Assign("age", gorm.Expr("age + ?", 1)).FirstOrCreate(&update20)

unfortunately this does not happen compared to if I used an absolute value .Assign("age", 20)

thus the gorm.Expr breaks the handlng

luckily you can throw a returning clause to restore expected behaviour

DB.Clauses(clause.Returning{}).Where("name = ?", "jinzhu").Assign("age", gorm.Expr("age + ?", 5)).FirstOrCreate(&update2)

this should be fixed; documentation can solve the issue as a stop gap

GORM_DIALECT=postgres go test -v
2025/09/17 17:34:49 testing postgres...
=== RUN   TestGORM

2025/09/17 17:34:49 /Users/allen/dev/playground/main_test.go:17
[0.484ms] [rows:0] SELECT * FROM "users" WHERE "users"."deleted_at" IS NULL ORDER BY "users"."id" LIMIT 1

2025/09/17 17:34:49 /Users/allen/dev/playground/main_test.go:17
[0.929ms] [rows:1] INSERT INTO "users" ("created_at","updated_at","deleted_at","name","age","birthday","company_id","manager_id","active") VALUES ('2025-09-17 17:34:49.47','2025-09-17 17:34:49.47',NULL,'jinzhu',18,NULL,NULL,NULL,false) RETURNING "id"
    main_test.go:23: Success, got user name: jinzhu, expected: jinzhu

2025/09/17 17:34:49 /Users/allen/dev/playground/main_test.go:30
[0.361ms] [rows:1] SELECT * FROM "users" WHERE name = 'jinzhu' AND "users"."deleted_at" IS NULL ORDER BY "users"."id" LIMIT 1

2025/09/17 17:34:49 /Users/allen/dev/playground/main_test.go:30
[0.695ms] [rows:1] UPDATE "users" SET "age"=19,"updated_at"='2025-09-17 17:34:49.471' WHERE name = 'jinzhu' AND "users"."deleted_at" IS NULL AND "id" = 1
    main_test.go:36: Success, got user age: 19, expected: 19

2025/09/17 17:34:49 /Users/allen/dev/playground/main_test.go:43
[0.186ms] [rows:1] SELECT * FROM "users" WHERE name = 'jinzhu' AND "users"."deleted_at" IS NULL ORDER BY "users"."id" LIMIT 1

2025/09/17 17:34:49 /Users/allen/dev/playground/main_test.go:43
[0.680ms] [rows:1] UPDATE "users" SET "age"=age + 1,"updated_at"='2025-09-17 17:34:49.472' WHERE name = 'jinzhu' AND "users"."deleted_at" IS NULL AND "id" = 1
    main_test.go:47: Failed, got user age: 19, expected: 20

2025/09/17 17:34:49 /Users/allen/dev/playground/main_test.go:55
[0.188ms] [rows:1] SELECT * FROM "users" WHERE name = 'jinzhu' AND "users"."deleted_at" IS NULL ORDER BY "users"."id" LIMIT 1
    main_test.go:61: Success, got user 1 with age 20

2025/09/17 17:34:49 /Users/allen/dev/playground/main_test.go:67
[0.181ms] [rows:1] SELECT * FROM "users" WHERE name = 'jinzhu' AND "users"."deleted_at" IS NULL ORDER BY "users"."id" LIMIT 1

2025/09/17 17:34:49 /Users/allen/dev/playground/main_test.go:67
[0.723ms] [rows:1] UPDATE "users" SET "age"=age + 5,"updated_at"='2025-09-17 17:34:49.473' WHERE name = 'jinzhu' AND "users"."deleted_at" IS NULL AND "id" = 1 RETURNING *
    main_test.go:73: Success, got user age: 25, expected: 25
--- FAIL: TestGORM (0.00s)
FAIL

@allen-moonshot allen-moonshot changed the title feat: FirstOrCreate's does not return Assign result into struct bug: FirstOrCreate's does not return Assign result into struct Sep 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant