FirstOrInit finds the first matching record, otherwise if not found initializes a new instance with given conds. Each conds must be a struct or map. FirstOrInit never modifies the database. It is often used with Assign and Attrs. // assign an email if the record is not found db.Where(User{Name:
(dest interface{}, conds ...interface{})
| 317 | // db.Where(User{Name: "jinzhu"}).Assign(User{Email: "fake@fake.org"}).FirstOrInit(&user) |
| 318 | // // user -> User{Name: "jinzhu", Age: 20, Email: "fake@fake.org"} |
| 319 | func (db *DB) FirstOrInit(dest interface{}, conds ...interface{}) (tx *DB) { |
| 320 | queryTx := db.Limit(1).Order(clause.OrderByColumn{ |
| 321 | Column: clause.Column{Table: clause.CurrentTable, Name: clause.PrimaryKey}, |
| 322 | }) |
| 323 | |
| 324 | if tx = queryTx.Find(dest, conds...); tx.RowsAffected == 0 { |
| 325 | if c, ok := tx.Statement.Clauses["WHERE"]; ok { |
| 326 | if where, ok := c.Expression.(clause.Where); ok { |
| 327 | tx.assignInterfacesToValue(where.Exprs) |
| 328 | } |
| 329 | } |
| 330 | |
| 331 | // initialize with attrs, conds |
| 332 | if len(tx.Statement.attrs) > 0 { |
| 333 | tx.assignInterfacesToValue(tx.Statement.attrs...) |
| 334 | } |
| 335 | } |
| 336 | |
| 337 | // initialize with attrs, conds |
| 338 | if len(tx.Statement.assigns) > 0 { |
| 339 | tx.assignInterfacesToValue(tx.Statement.assigns...) |
| 340 | } |
| 341 | return |
| 342 | } |
| 343 | |
| 344 | // FirstOrCreate finds the first matching record, otherwise if not found creates a new instance with given conds. |
| 345 | // Each conds must be a struct or map. |