FirstOrCreate finds the first matching record, otherwise if not found creates a new instance with given conds. Each conds must be a struct or map. Using FirstOrCreate in conjunction with Assign will result in an update to the database even if the record exists. // assign an email if the record is
(dest interface{}, conds ...interface{})
| 356 | // // user -> User{Name: "jinzhu", Age: 20, Email: "fake@fake.org"} |
| 357 | // // result.RowsAffected -> 1 |
| 358 | func (db *DB) FirstOrCreate(dest interface{}, conds ...interface{}) (tx *DB) { |
| 359 | tx = db.getInstance() |
| 360 | queryTx := db.Session(&Session{}).Limit(1).Order(clause.OrderByColumn{ |
| 361 | Column: clause.Column{Table: clause.CurrentTable, Name: clause.PrimaryKey}, |
| 362 | }) |
| 363 | |
| 364 | result := queryTx.Find(dest, conds...) |
| 365 | if result.Error != nil { |
| 366 | tx.Error = result.Error |
| 367 | return tx |
| 368 | } |
| 369 | |
| 370 | if result.RowsAffected == 0 { |
| 371 | if c, ok := result.Statement.Clauses["WHERE"]; ok { |
| 372 | if where, ok := c.Expression.(clause.Where); ok { |
| 373 | result.assignInterfacesToValue(where.Exprs) |
| 374 | } |
| 375 | } |
| 376 | |
| 377 | // initialize with attrs, conds |
| 378 | if len(db.Statement.attrs) > 0 { |
| 379 | result.assignInterfacesToValue(db.Statement.attrs...) |
| 380 | } |
| 381 | |
| 382 | // initialize with attrs, conds |
| 383 | if len(db.Statement.assigns) > 0 { |
| 384 | result.assignInterfacesToValue(db.Statement.assigns...) |
| 385 | } |
| 386 | |
| 387 | return tx.Create(dest) |
| 388 | } else if len(db.Statement.assigns) > 0 { |
| 389 | exprs := tx.Statement.BuildCondition(db.Statement.assigns[0], db.Statement.assigns[1:]...) |
| 390 | assigns := map[string]interface{}{} |
| 391 | for i := 0; i < len(exprs); i++ { |
| 392 | expr := exprs[i] |
| 393 | |
| 394 | if eq, ok := expr.(clause.AndConditions); ok { |
| 395 | exprs = append(exprs, eq.Exprs...) |
| 396 | } else if eq, ok := expr.(clause.Eq); ok { |
| 397 | switch column := eq.Column.(type) { |
| 398 | case string: |
| 399 | assigns[column] = eq.Value |
| 400 | case clause.Column: |
| 401 | assigns[column.Name] = eq.Value |
| 402 | } |
| 403 | } |
| 404 | } |
| 405 | |
| 406 | return tx.Model(dest).Updates(assigns) |
| 407 | } |
| 408 | |
| 409 | return tx |
| 410 | } |
| 411 | |
| 412 | // Update updates column with value using callbacks. Reference: https://gorm.io/docs/update.html#Update-Changed-Fields |
| 413 | func (db *DB) Update(column string, value interface{}) (tx *DB) { |