sqlboiler/templates/07_relationship_to_one_eager.tpl
Aaron L 59c238539d Attach all eagerly loaded models in to-one
- The problem here is that due to the nature of the relationship and the
  way the loop was set up it was possible to miss some relationships:

A _ C
 \_ D

B _ E
 \_ F

Since we looped over A and B and did a break when we found something to
attach it to (in this example A would find C) it would break. What we
should be looping through is CDEF and finding a home for each one.

Did the same change in to_one though it doesn't matter since it's
one-to-one.

to-many is untouched because it's already looping over CDEF and finding
a home for it because the relationship is reversed.

- Fix #98
2017-01-26 22:06:47 -08:00

93 lines
2.5 KiB
Smarty

{{- if .Table.IsJoinTable -}}
{{- else -}}
{{- $dot := . -}}
{{- range .Table.FKeys -}}
{{- $txt := txtsFromFKey $dot.Tables $dot.Table . -}}
{{- $varNameSingular := $dot.Table.Name | singular | camelCase -}}
{{- $arg := printf "maybe%s" $txt.LocalTable.NameGo -}}
{{- $slice := printf "%sSlice" $txt.LocalTable.NameGo}}
// Load{{$txt.Function.Name}} allows an eager lookup of values, cached into the
// loaded structs of the objects.
func ({{$varNameSingular}}L) Load{{$txt.Function.Name}}(e boil.Executor, singular bool, {{$arg}} interface{}) error {
var slice []*{{$txt.LocalTable.NameGo}}
var object *{{$txt.LocalTable.NameGo}}
count := 1
if singular {
object = {{$arg}}.(*{{$txt.LocalTable.NameGo}})
} else {
slice = *{{$arg}}.(*{{$slice}})
count = len(slice)
}
args := make([]interface{}, count)
if singular {
if object.R == nil {
object.R = &{{$varNameSingular}}R{}
}
args[0] = object.{{$txt.LocalTable.ColumnNameGo}}
} else {
for i, obj := range slice {
if obj.R == nil {
obj.R = &{{$varNameSingular}}R{}
}
args[i] = obj.{{$txt.LocalTable.ColumnNameGo}}
}
}
query := fmt.Sprintf(
"select * from {{.ForeignTable | $dot.SchemaTable}} where {{.ForeignColumn | $dot.Quotes}} in (%s)",
strmangle.Placeholders(dialect.IndexPlaceholders, count, 1, 1),
)
if boil.DebugMode {
fmt.Fprintf(boil.DebugWriter, "%s\n%v\n", query, args)
}
results, err := e.Query(query, args...)
if err != nil {
return errors.Wrap(err, "failed to eager load {{$txt.ForeignTable.NameGo}}")
}
defer results.Close()
var resultSlice []*{{$txt.ForeignTable.NameGo}}
if err = queries.Bind(results, &resultSlice); err != nil {
return errors.Wrap(err, "failed to bind eager loaded slice {{$txt.ForeignTable.NameGo}}")
}
{{if not $dot.NoHooks -}}
if len({{$varNameSingular}}AfterSelectHooks) != 0 {
for _, obj := range resultSlice {
if err := obj.doAfterSelectHooks(e); err != nil {
return err
}
}
}
{{- end}}
if len(resultSlice) == 0 {
return nil
}
if singular {
object.R.{{$txt.Function.Name}} = resultSlice[0]
return nil
}
for _, local := range slice {
for _, foreign := range resultSlice {
{{if $txt.Function.UsesBytes -}}
if 0 == bytes.Compare(local.{{$txt.Function.LocalAssignment}}, foreign.{{$txt.Function.ForeignAssignment}}) {
{{else -}}
if local.{{$txt.Function.LocalAssignment}} == foreign.{{$txt.Function.ForeignAssignment}} {
{{end -}}
local.R.{{$txt.Function.Name}} = foreign
break
}
}
}
return nil
}
{{end -}}{{/* range */}}
{{end}}{{/* join table */}}