When using `Preload` on a `many2many` association, the
`Query` callback chain was not being called. This made
it difficult to write a plugin that could reliably get
called regardless of how objects were being queried.
Now `handleManyToManyPreload` will call the `Query`
callback chain for each object that is retrieved by
following the association.
Since the data has already been read by the
`handleManyToManyPreload` method, a new scope setting
called `gorm:skip_queryCallback` is set to `true` before
calling the callbacks. Callbacks can check for the
presence of this setting if they should not be run; the
default `queryCallback` is an example of this case.
Fixesjinzhu/gorm#1621.
When using `Preload` to include the results of a "has many"
relationship, Gorm previously returned an uninitialized slice for any
such relations that bore zero records. This distinction was most
apparent when the results were marshalled to a JSON representation--a
record with zero related records would be represented with `null`.
For example, consider the following schema:
id | name
---|------
1 | Lorin
2 | Sue
id | p_id | value
---|------|-------------------
1 | 1 | lorin@example.com
2 | 1 | lorin2@example.com
Querying with:
db.Preload("Email").Find(&people)
And marshalling the resulting value of `people` to JSON would yield the
following string:
[
{
"name": "Lorin",
"email": [
"lorin@example.com",
"lorin2@example.com"
]
},
{
"name": "Sue",
"email": null
}
]
Beyond being inconsistent, the value `null` in this response differs
semantically from the actual state of the database. The database
actually has zero related records for the second user, so a JSON value
of `[]` is appropriate.
Update the callback that processes "has many" relationships to
communicate empty query results with an empty slice.
This was actually broken with the refactoring. I added a test to catch
the other place the error was occuring. See the new
TestManyToManyPreloadForNestedPointer test in preload_test.go.