| 479 | } |
| 480 | |
| 481 | func (c chainG[T]) Preload(association string, query func(db PreloadBuilder) error) ChainInterface[T] { |
| 482 | return c.with(func(db *DB) *DB { |
| 483 | return db.Preload(association, func(tx *DB) *DB { |
| 484 | q := preloadBuilder{db: tx.getInstance()} |
| 485 | if query != nil { |
| 486 | if err := query(&q); err != nil { |
| 487 | db.AddError(err) |
| 488 | } |
| 489 | } |
| 490 | |
| 491 | relation, ok := db.Statement.Schema.Relationships.Relations[association] |
| 492 | if !ok { |
| 493 | if preloadFields := strings.Split(association, "."); len(preloadFields) > 1 { |
| 494 | relationships := &db.Statement.Schema.Relationships |
| 495 | for _, field := range preloadFields { |
| 496 | var ok bool |
| 497 | relation, ok = relationships.Relations[field] |
| 498 | if ok { |
| 499 | relationships = &relation.FieldSchema.Relationships |
| 500 | } else { |
| 501 | db.AddError(fmt.Errorf("relation %s not found", association)) |
| 502 | return nil |
| 503 | } |
| 504 | } |
| 505 | } else { |
| 506 | db.AddError(fmt.Errorf("relation %s not found", association)) |
| 507 | return nil |
| 508 | } |
| 509 | } |
| 510 | |
| 511 | if q.limitPerRecord > 0 { |
| 512 | if relation.JoinTable != nil { |
| 513 | tx.AddError(fmt.Errorf("many2many relation %s don't support LimitPerRecord", association)) |
| 514 | return tx |
| 515 | } |
| 516 | |
| 517 | refColumns := []clause.Column{} |
| 518 | for _, rel := range relation.References { |
| 519 | if rel.OwnPrimaryKey { |
| 520 | refColumns = append(refColumns, clause.Column{Name: rel.ForeignKey.DBName}) |
| 521 | } |
| 522 | } |
| 523 | |
| 524 | if len(refColumns) != 0 { |
| 525 | selectExpr := clause.CommaExpression{} |
| 526 | for _, column := range q.db.Statement.Selects { |
| 527 | selectExpr.Exprs = append(selectExpr.Exprs, clause.Expr{SQL: "?", Vars: []interface{}{clause.Column{Name: column}}}) |
| 528 | } |
| 529 | |
| 530 | if len(selectExpr.Exprs) == 0 { |
| 531 | selectExpr.Exprs = []clause.Expression{clause.Expr{SQL: "*", Vars: []interface{}{}}} |
| 532 | } |
| 533 | |
| 534 | partitionBy := clause.CommaExpression{} |
| 535 | for _, column := range refColumns { |
| 536 | partitionBy.Exprs = append(partitionBy.Exprs, clause.Expr{SQL: "?", Vars: []interface{}{clause.Column{Name: column.Name}}}) |
| 537 | } |
| 538 | |