Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EagerPreload: Added fix/tests for has_many with pointer foreign key #647

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions pop_test.go
Expand Up @@ -150,6 +150,8 @@ type Taxi struct {
UpdatedAt time.Time `db:"updated_at"`
}

type Taxis []Taxi

// Validate gets run every time you call a "Validate*" (ValidateAndSave, ValidateAndCreate, ValidateAndUpdate) method.
// This method is not required and may be deleted.
func (b *Book) Validate(tx *Connection) (*validate.Errors, error) {
Expand Down Expand Up @@ -180,6 +182,7 @@ type Address struct {
HouseNumber int `db:"house_number"`
CreatedAt time.Time `db:"created_at"`
UpdatedAt time.Time `db:"updated_at"`
TaxisToHere Taxis `has_many:"taxis" fk_id:"to_address_id" order_by:"created_at asc"`
}

type Addresses []Address
Expand Down
5 changes: 3 additions & 2 deletions preload_associations.go
Expand Up @@ -271,8 +271,9 @@ func preloadHasMany(tx *Connection, asoc *AssociationMetaInfo, mmi *ModelMetaInf
modelAssociationField := mmi.mapper.FieldByName(mvalue, asoc.Name)
for i := 0; i < slice.Elem().Len(); i++ {
asocValue := slice.Elem().Index(i)
if mmi.mapper.FieldByName(mvalue, "ID").Interface() == mmi.mapper.FieldByName(asocValue, foreignField.Path).Interface() ||
reflect.DeepEqual(mmi.mapper.FieldByName(mvalue, "ID"), mmi.mapper.FieldByName(asocValue, foreignField.Path)) {
valueField := reflect.Indirect(mmi.mapper.FieldByName(asocValue, foreignField.Path))
if mmi.mapper.FieldByName(mvalue, "ID").Interface() == valueField.Interface() ||
reflect.DeepEqual(mmi.mapper.FieldByName(mvalue, "ID"), valueField) {

switch {
case modelAssociationField.Kind() == reflect.Slice || modelAssociationField.Kind() == reflect.Array:
Expand Down
36 changes: 36 additions & 0 deletions preload_associations_test.go
Expand Up @@ -264,3 +264,39 @@ func Test_New_Implementation_For_BelongsTo_Ptr_Field(t *testing.T) {
SetEagerMode(EagerDefault)
})
}

func Test_New_Implementation_For_HasMany_Ptr_Field(t *testing.T) {
if PDB == nil {
t.Skip("skipping integration tests")
}
transaction(func(tx *Connection) {
a := require.New(t)
toAddress1 := Address{HouseNumber: 1, Street: "Destination Ave"}
a.NoError(tx.Create(&toAddress1))
taxi1 := Taxi{Model: "Ford", ToAddressID: &toAddress1.ID}
a.NoError(tx.Create(&taxi1))
taxi2 := Taxi{Model: "Honda", ToAddressID: &toAddress1.ID}
a.NoError(tx.Create(&taxi2))

taxiNilToAddress := Taxi{ToAddressID: nil}
a.NoError(tx.Create(&taxiNilToAddress))

toAddress2 := Address{HouseNumber: 2, Street: "Final Way"}
a.NoError(tx.Create(&toAddress2))
taxi3 := Taxi{Model: "Mazda", ToAddressID: &toAddress2.ID}
a.NoError(tx.Create(&taxi3))

SetEagerMode(EagerPreload)
addresses := []Address{}
a.NoError(tx.EagerPreload("TaxisToHere").Order("created_at").All(&addresses))
a.Len(addresses, 2)
a.NotNil(addresses[0].TaxisToHere)
a.Len(addresses[0].TaxisToHere, 2)
a.Equal(taxi1.Model, addresses[0].TaxisToHere[0].Model)
a.Equal(taxi2.Model, addresses[0].TaxisToHere[1].Model)
a.NotNil(addresses[1].TaxisToHere)
a.Len(addresses[1].TaxisToHere, 1)
a.Equal(taxi3.Model, addresses[1].TaxisToHere[0].Model)
SetEagerMode(EagerDefault)
})
}