gorm/association_test.go
Nikola Kovacs 6eb73ae654 Fix too long foreign key names in mysql.
The dialect must define its own foreign key generator method.
The previous default is available as a method on gorm.DefaultForeignKeyNamer
and can be embedded in other dialects.
The mysql dialect uses the first 24 characters plus an sha1 hash of the
full key name if the key name is more than 64 characters.
2016-05-22 00:13:26 +02:00

867 lines
26 KiB
Go

package gorm_test
import (
"fmt"
"os"
"reflect"
"sort"
"testing"
"github.com/jinzhu/gorm"
)
func TestBelongsTo(t *testing.T) {
post := Post{
Title: "post belongs to",
Body: "body belongs to",
Category: Category{Name: "Category 1"},
MainCategory: Category{Name: "Main Category 1"},
}
if err := DB.Save(&post).Error; err != nil {
t.Error("Got errors when save post", err)
}
if post.Category.ID == 0 || post.MainCategory.ID == 0 {
t.Errorf("Category's primary key should be updated")
}
if post.CategoryId.Int64 == 0 || post.MainCategoryId == 0 {
t.Errorf("post's foreign key should be updated")
}
// Query
var category1 Category
DB.Model(&post).Association("Category").Find(&category1)
if category1.Name != "Category 1" {
t.Errorf("Query belongs to relations with Association")
}
var mainCategory1 Category
DB.Model(&post).Association("MainCategory").Find(&mainCategory1)
if mainCategory1.Name != "Main Category 1" {
t.Errorf("Query belongs to relations with Association")
}
var category11 Category
DB.Model(&post).Related(&category11)
if category11.Name != "Category 1" {
t.Errorf("Query belongs to relations with Related")
}
if DB.Model(&post).Association("Category").Count() != 1 {
t.Errorf("Post's category count should be 1")
}
if DB.Model(&post).Association("MainCategory").Count() != 1 {
t.Errorf("Post's main category count should be 1")
}
// Append
var category2 = Category{
Name: "Category 2",
}
DB.Model(&post).Association("Category").Append(&category2)
if category2.ID == 0 {
t.Errorf("Category should has ID when created with Append")
}
var category21 Category
DB.Model(&post).Related(&category21)
if category21.Name != "Category 2" {
t.Errorf("Category should be updated with Append")
}
if DB.Model(&post).Association("Category").Count() != 1 {
t.Errorf("Post's category count should be 1")
}
// Replace
var category3 = Category{
Name: "Category 3",
}
DB.Model(&post).Association("Category").Replace(&category3)
if category3.ID == 0 {
t.Errorf("Category should has ID when created with Replace")
}
var category31 Category
DB.Model(&post).Related(&category31)
if category31.Name != "Category 3" {
t.Errorf("Category should be updated with Replace")
}
if DB.Model(&post).Association("Category").Count() != 1 {
t.Errorf("Post's category count should be 1")
}
// Delete
DB.Model(&post).Association("Category").Delete(&category2)
if DB.Model(&post).Related(&Category{}).RecordNotFound() {
t.Errorf("Should not delete any category when Delete a unrelated Category")
}
if post.Category.Name == "" {
t.Errorf("Post's category should not be reseted when Delete a unrelated Category")
}
DB.Model(&post).Association("Category").Delete(&category3)
if post.Category.Name != "" {
t.Errorf("Post's category should be reseted after Delete")
}
var category41 Category
DB.Model(&post).Related(&category41)
if category41.Name != "" {
t.Errorf("Category should be deleted with Delete")
}
if count := DB.Model(&post).Association("Category").Count(); count != 0 {
t.Errorf("Post's category count should be 0 after Delete, but got %v", count)
}
// Clear
DB.Model(&post).Association("Category").Append(&Category{
Name: "Category 2",
})
if DB.Model(&post).Related(&Category{}).RecordNotFound() {
t.Errorf("Should find category after append")
}
if post.Category.Name == "" {
t.Errorf("Post's category should has value after Append")
}
DB.Model(&post).Association("Category").Clear()
if post.Category.Name != "" {
t.Errorf("Post's category should be cleared after Clear")
}
if !DB.Model(&post).Related(&Category{}).RecordNotFound() {
t.Errorf("Should not find any category after Clear")
}
if count := DB.Model(&post).Association("Category").Count(); count != 0 {
t.Errorf("Post's category count should be 0 after Clear, but got %v", count)
}
// Check Association mode with soft delete
category6 := Category{
Name: "Category 6",
}
DB.Model(&post).Association("Category").Append(&category6)
if count := DB.Model(&post).Association("Category").Count(); count != 1 {
t.Errorf("Post's category count should be 1 after Append, but got %v", count)
}
DB.Delete(&category6)
if count := DB.Model(&post).Association("Category").Count(); count != 0 {
t.Errorf("Post's category count should be 0 after the category has been deleted, but got %v", count)
}
if err := DB.Model(&post).Association("Category").Find(&Category{}).Error; err == nil {
t.Errorf("Post's category is not findable after Delete")
}
if count := DB.Unscoped().Model(&post).Association("Category").Count(); count != 1 {
t.Errorf("Post's category count should be 1 when query with Unscoped, but got %v", count)
}
if err := DB.Unscoped().Model(&post).Association("Category").Find(&Category{}).Error; err != nil {
t.Errorf("Post's category should be findable when query with Unscoped, got %v", err)
}
}
func TestBelongsToOverrideForeignKey1(t *testing.T) {
type Profile struct {
gorm.Model
Name string
}
type User struct {
gorm.Model
Profile Profile `gorm:"ForeignKey:ProfileRefer"`
ProfileRefer int
}
if relation, ok := DB.NewScope(&User{}).FieldByName("Profile"); ok {
if relation.Relationship.Kind != "belongs_to" ||
!reflect.DeepEqual(relation.Relationship.ForeignFieldNames, []string{"ProfileRefer"}) ||
!reflect.DeepEqual(relation.Relationship.AssociationForeignFieldNames, []string{"ID"}) {
t.Errorf("Override belongs to foreign key with tag")
}
}
}
func TestBelongsToOverrideForeignKey2(t *testing.T) {
type Profile struct {
gorm.Model
Refer string
Name string
}
type User struct {
gorm.Model
Profile Profile `gorm:"ForeignKey:ProfileID;AssociationForeignKey:Refer"`
ProfileID int
}
if relation, ok := DB.NewScope(&User{}).FieldByName("Profile"); ok {
if relation.Relationship.Kind != "belongs_to" ||
!reflect.DeepEqual(relation.Relationship.ForeignFieldNames, []string{"ProfileID"}) ||
!reflect.DeepEqual(relation.Relationship.AssociationForeignFieldNames, []string{"Refer"}) {
t.Errorf("Override belongs to foreign key with tag")
}
}
}
func TestHasOne(t *testing.T) {
user := User{
Name: "has one",
CreditCard: CreditCard{Number: "411111111111"},
}
if err := DB.Save(&user).Error; err != nil {
t.Error("Got errors when save user", err.Error())
}
if user.CreditCard.UserId.Int64 == 0 {
t.Errorf("CreditCard's foreign key should be updated")
}
// Query
var creditCard1 CreditCard
DB.Model(&user).Related(&creditCard1)
if creditCard1.Number != "411111111111" {
t.Errorf("Query has one relations with Related")
}
var creditCard11 CreditCard
DB.Model(&user).Association("CreditCard").Find(&creditCard11)
if creditCard11.Number != "411111111111" {
t.Errorf("Query has one relations with Related")
}
if DB.Model(&user).Association("CreditCard").Count() != 1 {
t.Errorf("User's credit card count should be 1")
}
// Append
var creditcard2 = CreditCard{
Number: "411111111112",
}
DB.Model(&user).Association("CreditCard").Append(&creditcard2)
if creditcard2.ID == 0 {
t.Errorf("Creditcard should has ID when created with Append")
}
var creditcard21 CreditCard
DB.Model(&user).Related(&creditcard21)
if creditcard21.Number != "411111111112" {
t.Errorf("CreditCard should be updated with Append")
}
if DB.Model(&user).Association("CreditCard").Count() != 1 {
t.Errorf("User's credit card count should be 1")
}
// Replace
var creditcard3 = CreditCard{
Number: "411111111113",
}
DB.Model(&user).Association("CreditCard").Replace(&creditcard3)
if creditcard3.ID == 0 {
t.Errorf("Creditcard should has ID when created with Replace")
}
var creditcard31 CreditCard
DB.Model(&user).Related(&creditcard31)
if creditcard31.Number != "411111111113" {
t.Errorf("CreditCard should be updated with Replace")
}
if DB.Model(&user).Association("CreditCard").Count() != 1 {
t.Errorf("User's credit card count should be 1")
}
// Delete
DB.Model(&user).Association("CreditCard").Delete(&creditcard2)
var creditcard4 CreditCard
DB.Model(&user).Related(&creditcard4)
if creditcard4.Number != "411111111113" {
t.Errorf("Should not delete credit card when Delete a unrelated CreditCard")
}
if DB.Model(&user).Association("CreditCard").Count() != 1 {
t.Errorf("User's credit card count should be 1")
}
DB.Model(&user).Association("CreditCard").Delete(&creditcard3)
if !DB.Model(&user).Related(&CreditCard{}).RecordNotFound() {
t.Errorf("Should delete credit card with Delete")
}
if DB.Model(&user).Association("CreditCard").Count() != 0 {
t.Errorf("User's credit card count should be 0 after Delete")
}
// Clear
var creditcard5 = CreditCard{
Number: "411111111115",
}
DB.Model(&user).Association("CreditCard").Append(&creditcard5)
if DB.Model(&user).Related(&CreditCard{}).RecordNotFound() {
t.Errorf("Should added credit card with Append")
}
if DB.Model(&user).Association("CreditCard").Count() != 1 {
t.Errorf("User's credit card count should be 1")
}
DB.Model(&user).Association("CreditCard").Clear()
if !DB.Model(&user).Related(&CreditCard{}).RecordNotFound() {
t.Errorf("Credit card should be deleted with Clear")
}
if DB.Model(&user).Association("CreditCard").Count() != 0 {
t.Errorf("User's credit card count should be 0 after Clear")
}
// Check Association mode with soft delete
var creditcard6 = CreditCard{
Number: "411111111116",
}
DB.Model(&user).Association("CreditCard").Append(&creditcard6)
if count := DB.Model(&user).Association("CreditCard").Count(); count != 1 {
t.Errorf("User's credit card count should be 1 after Append, but got %v", count)
}
DB.Delete(&creditcard6)
if count := DB.Model(&user).Association("CreditCard").Count(); count != 0 {
t.Errorf("User's credit card count should be 0 after credit card deleted, but got %v", count)
}
if err := DB.Model(&user).Association("CreditCard").Find(&CreditCard{}).Error; err == nil {
t.Errorf("User's creditcard is not findable after Delete")
}
if count := DB.Unscoped().Model(&user).Association("CreditCard").Count(); count != 1 {
t.Errorf("User's credit card count should be 1 when query with Unscoped, but got %v", count)
}
if err := DB.Unscoped().Model(&user).Association("CreditCard").Find(&CreditCard{}).Error; err != nil {
t.Errorf("User's creditcard should be findable when query with Unscoped, got %v", err)
}
}
func TestHasOneOverrideForeignKey1(t *testing.T) {
type Profile struct {
gorm.Model
Name string
UserRefer uint
}
type User struct {
gorm.Model
Profile Profile `gorm:"ForeignKey:UserRefer"`
}
if relation, ok := DB.NewScope(&User{}).FieldByName("Profile"); ok {
if relation.Relationship.Kind != "has_one" ||
!reflect.DeepEqual(relation.Relationship.ForeignFieldNames, []string{"UserRefer"}) ||
!reflect.DeepEqual(relation.Relationship.AssociationForeignFieldNames, []string{"ID"}) {
t.Errorf("Override belongs to foreign key with tag")
}
}
}
func TestHasOneOverrideForeignKey2(t *testing.T) {
type Profile struct {
gorm.Model
Name string
UserID uint
}
type User struct {
gorm.Model
Refer string
Profile Profile `gorm:"ForeignKey:UserID;AssociationForeignKey:Refer"`
}
if relation, ok := DB.NewScope(&User{}).FieldByName("Profile"); ok {
if relation.Relationship.Kind != "has_one" ||
!reflect.DeepEqual(relation.Relationship.ForeignFieldNames, []string{"UserID"}) ||
!reflect.DeepEqual(relation.Relationship.AssociationForeignFieldNames, []string{"Refer"}) {
t.Errorf("Override belongs to foreign key with tag")
}
}
}
func TestHasMany(t *testing.T) {
post := Post{
Title: "post has many",
Body: "body has many",
Comments: []*Comment{{Content: "Comment 1"}, {Content: "Comment 2"}},
}
if err := DB.Save(&post).Error; err != nil {
t.Error("Got errors when save post", err)
}
for _, comment := range post.Comments {
if comment.PostId == 0 {
t.Errorf("comment's PostID should be updated")
}
}
var compareComments = func(comments []Comment, contents []string) bool {
var commentContents []string
for _, comment := range comments {
commentContents = append(commentContents, comment.Content)
}
sort.Strings(commentContents)
sort.Strings(contents)
return reflect.DeepEqual(commentContents, contents)
}
// Query
if DB.First(&Comment{}, "content = ?", "Comment 1").Error != nil {
t.Errorf("Comment 1 should be saved")
}
var comments1 []Comment
DB.Model(&post).Association("Comments").Find(&comments1)
if !compareComments(comments1, []string{"Comment 1", "Comment 2"}) {
t.Errorf("Query has many relations with Association")
}
var comments11 []Comment
DB.Model(&post).Related(&comments11)
if !compareComments(comments11, []string{"Comment 1", "Comment 2"}) {
t.Errorf("Query has many relations with Related")
}
if DB.Model(&post).Association("Comments").Count() != 2 {
t.Errorf("Post's comments count should be 2")
}
// Append
DB.Model(&post).Association("Comments").Append(&Comment{Content: "Comment 3"})
var comments2 []Comment
DB.Model(&post).Related(&comments2)
if !compareComments(comments2, []string{"Comment 1", "Comment 2", "Comment 3"}) {
t.Errorf("Append new record to has many relations")
}
if DB.Model(&post).Association("Comments").Count() != 3 {
t.Errorf("Post's comments count should be 3 after Append")
}
// Delete
DB.Model(&post).Association("Comments").Delete(comments11)
var comments3 []Comment
DB.Model(&post).Related(&comments3)
if !compareComments(comments3, []string{"Comment 3"}) {
t.Errorf("Delete an existing resource for has many relations")
}
if DB.Model(&post).Association("Comments").Count() != 1 {
t.Errorf("Post's comments count should be 1 after Delete 2")
}
// Replace
DB.Model(&Post{Id: 999}).Association("Comments").Replace()
var comments4 []Comment
DB.Model(&post).Related(&comments4)
if len(comments4) == 0 {
t.Errorf("Replace for other resource should not clear all comments")
}
DB.Model(&post).Association("Comments").Replace(&Comment{Content: "Comment 4"}, &Comment{Content: "Comment 5"})
var comments41 []Comment
DB.Model(&post).Related(&comments41)
if !compareComments(comments41, []string{"Comment 4", "Comment 5"}) {
t.Errorf("Replace has many relations")
}
// Clear
DB.Model(&Post{Id: 999}).Association("Comments").Clear()
var comments5 []Comment
DB.Model(&post).Related(&comments5)
if len(comments5) == 0 {
t.Errorf("Clear should not clear all comments")
}
DB.Model(&post).Association("Comments").Clear()
var comments51 []Comment
DB.Model(&post).Related(&comments51)
if len(comments51) != 0 {
t.Errorf("Clear has many relations")
}
// Check Association mode with soft delete
var comment6 = Comment{
Content: "comment 6",
}
DB.Model(&post).Association("Comments").Append(&comment6)
if count := DB.Model(&post).Association("Comments").Count(); count != 1 {
t.Errorf("post's comments count should be 1 after Append, but got %v", count)
}
DB.Delete(&comment6)
if count := DB.Model(&post).Association("Comments").Count(); count != 0 {
t.Errorf("post's comments count should be 0 after comment been deleted, but got %v", count)
}
var comments6 []Comment
if DB.Model(&post).Association("Comments").Find(&comments6); len(comments6) != 0 {
t.Errorf("post's comments count should be 0 when find with Find, but got %v", len(comments6))
}
if count := DB.Unscoped().Model(&post).Association("Comments").Count(); count != 1 {
t.Errorf("post's comments count should be 1 when query with Unscoped, but got %v", count)
}
var comments61 []Comment
if DB.Unscoped().Model(&post).Association("Comments").Find(&comments61); len(comments61) != 1 {
t.Errorf("post's comments count should be 1 when query with Unscoped, but got %v", len(comments61))
}
}
func TestHasManyOverrideForeignKey1(t *testing.T) {
type Profile struct {
gorm.Model
Name string
UserRefer uint
}
type User struct {
gorm.Model
Profile []Profile `gorm:"ForeignKey:UserRefer"`
}
if relation, ok := DB.NewScope(&User{}).FieldByName("Profile"); ok {
if relation.Relationship.Kind != "has_many" ||
!reflect.DeepEqual(relation.Relationship.ForeignFieldNames, []string{"UserRefer"}) ||
!reflect.DeepEqual(relation.Relationship.AssociationForeignFieldNames, []string{"ID"}) {
t.Errorf("Override belongs to foreign key with tag")
}
}
}
func TestHasManyOverrideForeignKey2(t *testing.T) {
type Profile struct {
gorm.Model
Name string
UserID uint
}
type User struct {
gorm.Model
Refer string
Profile []Profile `gorm:"ForeignKey:UserID;AssociationForeignKey:Refer"`
}
if relation, ok := DB.NewScope(&User{}).FieldByName("Profile"); ok {
if relation.Relationship.Kind != "has_many" ||
!reflect.DeepEqual(relation.Relationship.ForeignFieldNames, []string{"UserID"}) ||
!reflect.DeepEqual(relation.Relationship.AssociationForeignFieldNames, []string{"Refer"}) {
t.Errorf("Override belongs to foreign key with tag")
}
}
}
func TestManyToMany(t *testing.T) {
DB.Raw("delete from languages")
var languages = []Language{{Name: "ZH"}, {Name: "EN"}}
user := User{Name: "Many2Many", Languages: languages}
DB.Save(&user)
// Query
var newLanguages []Language
DB.Model(&user).Related(&newLanguages, "Languages")
if len(newLanguages) != len([]string{"ZH", "EN"}) {
t.Errorf("Query many to many relations")
}
DB.Model(&user).Association("Languages").Find(&newLanguages)
if len(newLanguages) != len([]string{"ZH", "EN"}) {
t.Errorf("Should be able to find many to many relations")
}
if DB.Model(&user).Association("Languages").Count() != len([]string{"ZH", "EN"}) {
t.Errorf("Count should return correct result")
}
// Append
DB.Model(&user).Association("Languages").Append(&Language{Name: "DE"})
if DB.Where("name = ?", "DE").First(&Language{}).RecordNotFound() {
t.Errorf("New record should be saved when append")
}
languageA := Language{Name: "AA"}
DB.Save(&languageA)
DB.Model(&User{Id: user.Id}).Association("Languages").Append(&languageA)
languageC := Language{Name: "CC"}
DB.Save(&languageC)
DB.Model(&user).Association("Languages").Append(&[]Language{{Name: "BB"}, languageC})
DB.Model(&User{Id: user.Id}).Association("Languages").Append(&[]Language{{Name: "DD"}, {Name: "EE"}})
totalLanguages := []string{"ZH", "EN", "DE", "AA", "BB", "CC", "DD", "EE"}
if DB.Model(&user).Association("Languages").Count() != len(totalLanguages) {
t.Errorf("All appended languages should be saved")
}
// Delete
user.Languages = []Language{}
DB.Model(&user).Association("Languages").Find(&user.Languages)
var language Language
DB.Where("name = ?", "EE").First(&language)
DB.Model(&user).Association("Languages").Delete(language, &language)
if DB.Model(&user).Association("Languages").Count() != len(totalLanguages)-1 || len(user.Languages) != len(totalLanguages)-1 {
t.Errorf("Relations should be deleted with Delete")
}
if DB.Where("name = ?", "EE").First(&Language{}).RecordNotFound() {
t.Errorf("Language EE should not be deleted")
}
DB.Where("name IN (?)", []string{"CC", "DD"}).Find(&languages)
user2 := User{Name: "Many2Many_User2", Languages: languages}
DB.Save(&user2)
DB.Model(&user).Association("Languages").Delete(languages, &languages)
if DB.Model(&user).Association("Languages").Count() != len(totalLanguages)-3 || len(user.Languages) != len(totalLanguages)-3 {
t.Errorf("Relations should be deleted with Delete")
}
if DB.Model(&user2).Association("Languages").Count() == 0 {
t.Errorf("Other user's relations should not be deleted")
}
// Replace
var languageB Language
DB.Where("name = ?", "BB").First(&languageB)
DB.Model(&user).Association("Languages").Replace(languageB)
if len(user.Languages) != 1 || DB.Model(&user).Association("Languages").Count() != 1 {
t.Errorf("Relations should be replaced")
}
DB.Model(&user).Association("Languages").Replace()
if len(user.Languages) != 0 || DB.Model(&user).Association("Languages").Count() != 0 {
t.Errorf("Relations should be replaced with empty")
}
DB.Model(&user).Association("Languages").Replace(&[]Language{{Name: "FF"}, {Name: "JJ"}})
if len(user.Languages) != 2 || DB.Model(&user).Association("Languages").Count() != len([]string{"FF", "JJ"}) {
t.Errorf("Relations should be replaced")
}
// Clear
DB.Model(&user).Association("Languages").Clear()
if len(user.Languages) != 0 || DB.Model(&user).Association("Languages").Count() != 0 {
t.Errorf("Relations should be cleared")
}
// Check Association mode with soft delete
var language6 = Language{
Name: "language 6",
}
DB.Model(&user).Association("Languages").Append(&language6)
if count := DB.Model(&user).Association("Languages").Count(); count != 1 {
t.Errorf("user's languages count should be 1 after Append, but got %v", count)
}
DB.Delete(&language6)
if count := DB.Model(&user).Association("Languages").Count(); count != 0 {
t.Errorf("user's languages count should be 0 after language been deleted, but got %v", count)
}
var languages6 []Language
if DB.Model(&user).Association("Languages").Find(&languages6); len(languages6) != 0 {
t.Errorf("user's languages count should be 0 when find with Find, but got %v", len(languages6))
}
if count := DB.Unscoped().Model(&user).Association("Languages").Count(); count != 1 {
t.Errorf("user's languages count should be 1 when query with Unscoped, but got %v", count)
}
var languages61 []Language
if DB.Unscoped().Model(&user).Association("Languages").Find(&languages61); len(languages61) != 1 {
t.Errorf("user's languages count should be 1 when query with Unscoped, but got %v", len(languages61))
}
}
func TestRelated(t *testing.T) {
user := User{
Name: "jinzhu",
BillingAddress: Address{Address1: "Billing Address - Address 1"},
ShippingAddress: Address{Address1: "Shipping Address - Address 1"},
Emails: []Email{{Email: "jinzhu@example.com"}, {Email: "jinzhu-2@example@example.com"}},
CreditCard: CreditCard{Number: "1234567890"},
Company: Company{Name: "company1"},
}
if err := DB.Save(&user).Error; err != nil {
t.Errorf("No error should happen when saving user")
}
if user.CreditCard.ID == 0 {
t.Errorf("After user save, credit card should have id")
}
if user.BillingAddress.ID == 0 {
t.Errorf("After user save, billing address should have id")
}
if user.Emails[0].Id == 0 {
t.Errorf("After user save, billing address should have id")
}
var emails []Email
DB.Model(&user).Related(&emails)
if len(emails) != 2 {
t.Errorf("Should have two emails")
}
var emails2 []Email
DB.Model(&user).Where("email = ?", "jinzhu@example.com").Related(&emails2)
if len(emails2) != 1 {
t.Errorf("Should have two emails")
}
var emails3 []*Email
DB.Model(&user).Related(&emails3)
if len(emails3) != 2 {
t.Errorf("Should have two emails")
}
var user1 User
DB.Model(&user).Related(&user1.Emails)
if len(user1.Emails) != 2 {
t.Errorf("Should have only one email match related condition")
}
var address1 Address
DB.Model(&user).Related(&address1, "BillingAddressId")
if address1.Address1 != "Billing Address - Address 1" {
t.Errorf("Should get billing address from user correctly")
}
user1 = User{}
DB.Model(&address1).Related(&user1, "BillingAddressId")
if DB.NewRecord(user1) {
t.Errorf("Should get user from address correctly")
}
var user2 User
DB.Model(&emails[0]).Related(&user2)
if user2.Id != user.Id || user2.Name != user.Name {
t.Errorf("Should get user from email correctly")
}
var creditcard CreditCard
var user3 User
DB.First(&creditcard, "number = ?", "1234567890")
DB.Model(&creditcard).Related(&user3)
if user3.Id != user.Id || user3.Name != user.Name {
t.Errorf("Should get user from credit card correctly")
}
if !DB.Model(&CreditCard{}).Related(&User{}).RecordNotFound() {
t.Errorf("RecordNotFound for Related")
}
var company Company
if DB.Model(&user).Related(&company, "Company").RecordNotFound() || company.Name != "company1" {
t.Errorf("RecordNotFound for Related")
}
}
func TestForeignKey(t *testing.T) {
for _, structField := range DB.NewScope(&User{}).GetStructFields() {
for _, foreignKey := range []string{"BillingAddressID", "ShippingAddressId", "CompanyID"} {
if structField.Name == foreignKey && !structField.IsForeignKey {
t.Errorf(fmt.Sprintf("%v should be foreign key", foreignKey))
}
}
}
for _, structField := range DB.NewScope(&Email{}).GetStructFields() {
for _, foreignKey := range []string{"UserId"} {
if structField.Name == foreignKey && !structField.IsForeignKey {
t.Errorf(fmt.Sprintf("%v should be foreign key", foreignKey))
}
}
}
for _, structField := range DB.NewScope(&Post{}).GetStructFields() {
for _, foreignKey := range []string{"CategoryId", "MainCategoryId"} {
if structField.Name == foreignKey && !structField.IsForeignKey {
t.Errorf(fmt.Sprintf("%v should be foreign key", foreignKey))
}
}
}
for _, structField := range DB.NewScope(&Comment{}).GetStructFields() {
for _, foreignKey := range []string{"PostId"} {
if structField.Name == foreignKey && !structField.IsForeignKey {
t.Errorf(fmt.Sprintf("%v should be foreign key", foreignKey))
}
}
}
}
func TestLongForeignKey(t *testing.T) {
if dialect := os.Getenv("GORM_DIALECT"); dialect == "" || dialect == "sqlite" {
// sqlite does not support ADD CONSTRAINT in ALTER TABLE
return
}
targetScope := DB.NewScope(&ReallyLongTableNameToTestMySQLNameLengthLimit{})
targetTableName := targetScope.TableName()
modelScope := DB.NewScope(&NotSoLongTableName{})
modelField, ok := modelScope.FieldByName("ReallyLongThingID")
if !ok {
t.Fatalf("Failed to get field by name: ReallyLongThingID")
}
targetField, ok := targetScope.FieldByName("ID")
if !ok {
t.Fatalf("Failed to get field by name: ID")
}
dest := fmt.Sprintf("%v(%v)", targetTableName, targetField.DBName)
err := DB.Model(&NotSoLongTableName{}).AddForeignKey(modelField.DBName, dest, "CASCADE", "CASCADE").Error
if err != nil {
t.Fatalf(fmt.Sprintf("Failed to create foreign key: %v", err))
}
}