JoinsOn unit test + use all primary keys

This commit is contained in:
Adrien Carreira 2021-07-17 15:45:15 +02:00 committed by Jinzhu
parent 895c1178a0
commit 52cc438d07
5 changed files with 32 additions and 4 deletions

View File

@ -125,7 +125,7 @@ func BuildQuerySQL(db *gorm.DB) {
}) })
} }
if join.On != nil { if join.On == nil {
exprs := make([]clause.Expression, len(relation.References)) exprs := make([]clause.Expression, len(relation.References))
for idx, ref := range relation.References { for idx, ref := range relation.References {
if ref.OwnPrimaryKey { if ref.OwnPrimaryKey {
@ -153,10 +153,16 @@ func BuildQuerySQL(db *gorm.DB) {
ON: clause.Where{Exprs: exprs}, ON: clause.Where{Exprs: exprs},
}) })
} else { } else {
primaryFields := make([]clause.Column, len(relation.FieldSchema.PrimaryFieldDBNames))
for idx, ref := range relation.FieldSchema.PrimaryFieldDBNames {
primaryFields[idx] = clause.Column{Table: tableAliasName, Name: ref}
}
exprs := db.Statement.BuildCondition("(?) = (?)", primaryFields, join.On)
joins = append(joins, clause.Join{ joins = append(joins, clause.Join{
Type: clause.LeftJoin, Type: clause.LeftJoin,
Table: clause.Table{Name: relation.FieldSchema.Table, Alias: tableAliasName}, Table: clause.Table{Name: relation.FieldSchema.Table, Alias: tableAliasName},
ON: clause.Where{Exprs: []clause.Expression{join.On}}, ON: clause.Where{Exprs: exprs},
}) })
} }
} else { } else {

View File

@ -177,7 +177,7 @@ func (db *DB) Joins(query string, args ...interface{}) (tx *DB) {
return return
} }
func (db *DB) JoinsOn(query string, on clause.Expression, args ...interface{}) (tx *DB) { func (db *DB) JoinsOn(query string, on interface{}, args ...interface{}) (tx *DB) {
tx = db.getInstance() tx = db.getInstance()
tx.Statement.Joins = append(tx.Statement.Joins, join{Name: query, Conds: args, On: on}) tx.Statement.Joins = append(tx.Statement.Joins, join{Name: query, Conds: args, On: on})
return return

View File

@ -50,7 +50,7 @@ type Statement struct {
type join struct { type join struct {
Name string Name string
Conds []interface{} Conds []interface{}
On clause.Expression On interface{}
} }
// StatementModifier statement modifier interface // StatementModifier statement modifier interface

View File

@ -104,6 +104,26 @@ func TestJoinConds(t *testing.T) {
} }
} }
func TestJoinOn(t *testing.T) {
var user = *GetUser("joins-on", Config{Pets: 2})
DB.Save(&user)
var user1 User
onQuery := DB.Select("id").Where("user_id = users.id AND name = ?", "joins-on_pet_1").Model(&Pet{})
if err := DB.JoinsOn("NamedPet", onQuery).Where("users.name = ?", user.Name).First(&user1).Error; err != nil {
t.Fatalf("Failed to load with joins on, got error: %v", err)
}
AssertEqual(t, user1.NamedPet.Name, "joins-on_pet_1")
onQuery2 := DB.Select("id").Where("user_id = users.id AND name = ?", "joins-on_pet_2").Model(&Pet{})
var user2 User
if err := DB.JoinsOn("NamedPet", onQuery2).Where("users.name = ?", user.Name).First(&user2).Error; err != nil {
t.Fatalf("Failed to load with joins on, got error: %v", err)
}
AssertEqual(t, user2.NamedPet.Name, "joins-on_pet_2")
}
func TestJoinsWithSelect(t *testing.T) { func TestJoinsWithSelect(t *testing.T) {
type result struct { type result struct {
ID uint ID uint

View File

@ -11,6 +11,7 @@ import (
// He works in a Company (belongs to), he has a Manager (belongs to - single-table), and also managed a Team (has many - single-table) // He works in a Company (belongs to), he has a Manager (belongs to - single-table), and also managed a Team (has many - single-table)
// He speaks many languages (many to many) and has many friends (many to many - single-table) // He speaks many languages (many to many) and has many friends (many to many - single-table)
// His pet also has one Toy (has one - polymorphic) // His pet also has one Toy (has one - polymorphic)
// NamedPet is a reference to a Named `Pets` (has many)
type User struct { type User struct {
gorm.Model gorm.Model
Name string Name string
@ -18,6 +19,7 @@ type User struct {
Birthday *time.Time Birthday *time.Time
Account Account Account Account
Pets []*Pet Pets []*Pet
NamedPet *Pet
Toys []Toy `gorm:"polymorphic:Owner"` Toys []Toy `gorm:"polymorphic:Owner"`
CompanyID *int CompanyID *int
Company Company Company Company