forked from mirror/gorm
JoinsOn unit test + use all primary keys
This commit is contained in:
parent
895c1178a0
commit
52cc438d07
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue