github.com/dkishere/pop/v6@v6.103.1/preload_associations_test.go (about)

     1  package pop
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/gobuffalo/nulls"
     7  	"github.com/stretchr/testify/require"
     8  )
     9  
    10  func Test_New_Implementation_For_Nplus1(t *testing.T) {
    11  	if PDB == nil {
    12  		t.Skip("skipping integration tests")
    13  	}
    14  	transaction(func(tx *Connection) {
    15  		a := require.New(t)
    16  		for _, name := range []string{"Mark", "Joe", "Jane"} {
    17  			user := User{Name: nulls.NewString(name)}
    18  			a.NoError(tx.Create(&user))
    19  
    20  			book := Book{UserID: nulls.NewInt(user.ID)}
    21  			a.NoError(tx.Create(&book))
    22  
    23  			writer := Writer{Name: "Larry", BookID: book.ID}
    24  			a.NoError(tx.Create(&writer))
    25  
    26  			if name == "Mark" {
    27  				song := Song{UserID: user.ID}
    28  				a.NoError(tx.Create(&song))
    29  
    30  				address := Address{Street: "Pop"}
    31  				a.NoError(tx.Create(&address))
    32  
    33  				home := UsersAddress{UserID: user.ID, AddressID: address.ID}
    34  				a.NoError(tx.Create(&home))
    35  			}
    36  		}
    37  
    38  		users := []User{}
    39  		a.NoError(tx.All(&users))
    40  
    41  		// FILL THE HAS-MANY and HAS_ONE
    42  		a.NoError(preload(tx, &users))
    43  
    44  		a.Len(users[0].Books, 1)
    45  		a.Len(users[1].Books, 1)
    46  		a.Len(users[2].Books, 1)
    47  		a.Equal(users[0].FavoriteSong.UserID, users[0].ID)
    48  		a.Len(users[0].Houses, 1)
    49  
    50  		book := Book{}
    51  		a.NoError(tx.First(&book))
    52  		a.NoError(preload(tx, &book))
    53  		a.Len(book.Writers, 1)
    54  		a.Equal("Larry", book.Writers[0].Name)
    55  		a.Equal("Mark", book.User.Name.String)
    56  	})
    57  }
    58  
    59  func Test_New_Implementation_For_Nplus1_With_UUID(t *testing.T) {
    60  	if PDB == nil {
    61  		t.Skip("skipping integration tests")
    62  	}
    63  	transaction(func(tx *Connection) {
    64  		a := require.New(t)
    65  
    66  		courses := []Course{}
    67  		for i := 0; i < 3; i++ {
    68  			course := Course{}
    69  			a.NoError(tx.Create(&course))
    70  			courses = append(courses, course)
    71  			if i == 0 {
    72  				a.NoError(tx.Create(&CourseCode{
    73  					CourseID: course.ID,
    74  				}))
    75  			}
    76  		}
    77  
    78  		courseCodes := []CourseCode{}
    79  		a.NoError(tx.All(&courseCodes))
    80  		a.Len(courseCodes, 1)
    81  
    82  		// FILL THE HAS-MANY and HAS_ONE
    83  		a.NoError(preload(tx, &courseCodes))
    84  		a.Equal(courses[0].ID, courseCodes[0].Course.ID)
    85  
    86  		student := Student{}
    87  		a.NoError(tx.Create(&student))
    88  
    89  		parent := Parent{}
    90  		a.NoError(tx.Create(&parent))
    91  
    92  		a.NoError(tx.RawQuery("insert into parents_students(parent_id, student_id) values(?,?)", parent.ID.String(), student.ID.String()).Exec())
    93  
    94  		parents := []Parent{}
    95  		a.NoError(tx.All(&parents))
    96  
    97  		a.NoError(preload(tx, &parents))
    98  		a.Len(parents, 1)
    99  		a.Len(parents[0].Students, 1)
   100  		a.Equal(student.ID, parents[0].Students[0].ID)
   101  	})
   102  }
   103  
   104  func Test_New_Implementation_For_Nplus1_Single(t *testing.T) {
   105  	if PDB == nil {
   106  		t.Skip("skipping integration tests")
   107  	}
   108  	transaction(func(tx *Connection) {
   109  		a := require.New(t)
   110  		for _, name := range []string{"Mark", "Joe", "Jane"} {
   111  			user := User{Name: nulls.NewString(name)}
   112  			a.NoError(tx.Create(&user))
   113  
   114  			book := Book{UserID: nulls.NewInt(user.ID)}
   115  			a.NoError(tx.Create(&book))
   116  
   117  			writer := Writer{Name: "Larry", BookID: book.ID}
   118  			a.NoError(tx.Create(&writer))
   119  
   120  			if name == "Mark" {
   121  				song := Song{UserID: user.ID}
   122  				a.NoError(tx.Create(&song))
   123  
   124  				address := Address{Street: "Pop"}
   125  				a.NoError(tx.Create(&address))
   126  
   127  				home := UsersAddress{UserID: user.ID, AddressID: address.ID}
   128  				a.NoError(tx.Create(&home))
   129  			}
   130  		}
   131  
   132  		users := []User{}
   133  		a.NoError(tx.All(&users))
   134  
   135  		// FILL THE HAS-MANY and HAS_ONE
   136  		a.NoError(preload(tx, &users, "Books"))
   137  
   138  		a.Len(users[0].Books, 1)
   139  		a.Len(users[1].Books, 1)
   140  		a.Len(users[2].Books, 1)
   141  		a.Zero(users[0].FavoriteSong.UserID)
   142  		a.Len(users[0].Houses, 0)
   143  	})
   144  }
   145  
   146  func Test_New_Implementation_For_Nplus1_Nested(t *testing.T) {
   147  	if PDB == nil {
   148  		t.Skip("skipping integration tests")
   149  	}
   150  	transaction(func(tx *Connection) {
   151  		a := require.New(t)
   152  		var song Song
   153  		for _, name := range []string{"Mark", "Joe", "Jane"} {
   154  			user := User{Name: nulls.NewString(name)}
   155  			a.NoError(tx.Create(&user))
   156  
   157  			book := Book{UserID: nulls.NewInt(user.ID)}
   158  			a.NoError(tx.Create(&book))
   159  
   160  			if name == "Mark" {
   161  				song = Song{UserID: user.ID}
   162  				a.NoError(tx.Create(&song))
   163  
   164  				address := Address{Street: "Pop"}
   165  				a.NoError(tx.Create(&address))
   166  
   167  				home := UsersAddress{UserID: user.ID, AddressID: address.ID}
   168  				a.NoError(tx.Create(&home))
   169  			}
   170  		}
   171  
   172  		SetEagerMode(EagerPreload)
   173  		users := []User{}
   174  		a.NoError(tx.Eager("Houses", "Books", "Books.User.FavoriteSong").All(&users))
   175  		a.Len(users[0].Books, 1)
   176  		a.Len(users[1].Books, 1)
   177  		a.Len(users[2].Books, 1)
   178  		a.Len(users[0].Houses, 1)
   179  
   180  		a.Equal(users[0].ID, users[0].Books[0].User.ID)
   181  		a.Equal(song.ID, users[0].Books[0].User.FavoriteSong.ID)
   182  		SetEagerMode(EagerDefault)
   183  	})
   184  }
   185  
   186  func Test_New_Implementation_For_Nplus1_BelongsTo_Not_Underscore(t *testing.T) {
   187  	if PDB == nil {
   188  		t.Skip("skipping integration tests")
   189  	}
   190  	transaction(func(tx *Connection) {
   191  		a := require.New(t)
   192  		user := User{Name: nulls.NewString("Mark")}
   193  		a.NoError(tx.Create(&user))
   194  
   195  		taxi := Taxi{UserID: nulls.NewInt(user.ID)}
   196  		a.NoError(tx.Create(&taxi))
   197  
   198  		SetEagerMode(EagerPreload)
   199  		taxis := []Taxi{}
   200  		a.NoError(tx.EagerPreload().All(&taxis))
   201  		a.Len(taxis, 1)
   202  		a.Equal("Mark", taxis[0].Driver.Name.String)
   203  		SetEagerMode(EagerDefault)
   204  	})
   205  }
   206  
   207  func Test_New_Implementation_For_BelongsTo_Multiple_Fields(t *testing.T) {
   208  	if PDB == nil {
   209  		t.Skip("skipping integration tests")
   210  	}
   211  	transaction(func(tx *Connection) {
   212  		a := require.New(t)
   213  		user := User{Name: nulls.NewString("Mark")}
   214  		a.NoError(tx.Create(&user))
   215  
   216  		address := Address{HouseNumber: 2, Street: "Street One"}
   217  		a.NoError(tx.Create(&address))
   218  
   219  		taxi := Taxi{UserID: nulls.NewInt(user.ID), AddressID: nulls.NewInt(address.ID)}
   220  		a.NoError(tx.Create(&taxi))
   221  
   222  		book := Book{TaxiID: nulls.NewInt(taxi.ID), Title: "My Book"}
   223  		a.NoError(tx.Create(&book))
   224  
   225  		SetEagerMode(EagerPreload)
   226  		books := []Book{}
   227  		a.NoError(tx.EagerPreload("Taxi.Driver", "Taxi.Address").All(&books))
   228  		a.Len(books, 1)
   229  		a.Equal(user.Name.String, books[0].Taxi.Driver.Name.String)
   230  		a.Equal(address.Street, books[0].Taxi.Address.Street)
   231  		SetEagerMode(EagerDefault)
   232  	})
   233  }
   234  
   235  func Test_New_Implementation_For_BelongsTo_Ptr_Field(t *testing.T) {
   236  	if PDB == nil {
   237  		t.Skip("skipping integration tests")
   238  	}
   239  	transaction(func(tx *Connection) {
   240  		a := require.New(t)
   241  		toAddress := Address{HouseNumber: 1, Street: "Destination Ave"}
   242  		a.NoError(tx.Create(&toAddress))
   243  
   244  		taxi := Taxi{ToAddressID: &toAddress.ID}
   245  		a.NoError(tx.Create(&taxi))
   246  
   247  		book1 := Book{TaxiID: nulls.NewInt(taxi.ID), Title: "My Book"}
   248  		a.NoError(tx.Create(&book1))
   249  
   250  		taxiNilToAddress := Taxi{ToAddressID: nil}
   251  		a.NoError(tx.Create(&taxiNilToAddress))
   252  
   253  		book2 := Book{TaxiID: nulls.NewInt(taxiNilToAddress.ID), Title: "Another Book"}
   254  		a.NoError(tx.Create(&book2))
   255  
   256  		SetEagerMode(EagerPreload)
   257  		books := []Book{}
   258  		a.NoError(tx.EagerPreload("Taxi.ToAddress").Order("created_at").All(&books))
   259  		a.Len(books, 2)
   260  		a.Equal(toAddress.Street, books[0].Taxi.ToAddress.Street)
   261  		a.NotNil(books[0].Taxi.ToAddressID)
   262  		a.Nil(books[1].Taxi.ToAddress)
   263  		a.Nil(books[1].Taxi.ToAddressID)
   264  		SetEagerMode(EagerDefault)
   265  	})
   266  }
   267  
   268  func Test_New_Implementation_For_HasMany_Ptr_Field(t *testing.T) {
   269  	if PDB == nil {
   270  		t.Skip("skipping integration tests")
   271  	}
   272  	transaction(func(tx *Connection) {
   273  		a := require.New(t)
   274  		toAddress1 := Address{HouseNumber: 1, Street: "Destination Ave"}
   275  		a.NoError(tx.Create(&toAddress1))
   276  		taxi1 := Taxi{Model: "Ford", ToAddressID: &toAddress1.ID}
   277  		a.NoError(tx.Create(&taxi1))
   278  		taxi2 := Taxi{Model: "Honda", ToAddressID: &toAddress1.ID}
   279  		a.NoError(tx.Create(&taxi2))
   280  
   281  		taxiNilToAddress := Taxi{ToAddressID: nil}
   282  		a.NoError(tx.Create(&taxiNilToAddress))
   283  
   284  		toAddress2 := Address{HouseNumber: 2, Street: "Final Way"}
   285  		a.NoError(tx.Create(&toAddress2))
   286  		taxi3 := Taxi{Model: "Mazda", ToAddressID: &toAddress2.ID}
   287  		a.NoError(tx.Create(&taxi3))
   288  
   289  		SetEagerMode(EagerPreload)
   290  		addresses := []Address{}
   291  		a.NoError(tx.EagerPreload("TaxisToHere").Order("created_at").All(&addresses))
   292  		a.Len(addresses, 2)
   293  		a.NotNil(addresses[0].TaxisToHere)
   294  		a.Len(addresses[0].TaxisToHere, 2)
   295  		a.Equal(taxi1.Model, addresses[0].TaxisToHere[0].Model)
   296  		a.Equal(taxi2.Model, addresses[0].TaxisToHere[1].Model)
   297  		a.NotNil(addresses[1].TaxisToHere)
   298  		a.Len(addresses[1].TaxisToHere, 1)
   299  		a.Equal(taxi3.Model, addresses[1].TaxisToHere[0].Model)
   300  		SetEagerMode(EagerDefault)
   301  	})
   302  }