feat(Scopes): restored the ability to set the model from Scopes

This commit is contained in:
SystemGlitch 2022-11-04 14:31:17 +01:00
parent 3df271759b
commit 2dd6140e7a
No known key found for this signature in database
GPG Key ID: E09ED82897AEE53B
2 changed files with 69 additions and 16 deletions

View File

@ -84,22 +84,7 @@ func (p *processor) Execute(db *DB) *DB {
resetBuildClauses = true resetBuildClauses = true
} }
// assign model values modelParseError := p.parseModelValue(db, stmt)
if stmt.Model == nil {
stmt.Model = stmt.Dest
} else if stmt.Dest == nil {
stmt.Dest = stmt.Model
}
var modelParseError error
// parse model values
if stmt.Model != nil {
if modelParseError = stmt.Parse(stmt.Model); modelParseError != nil && (!errors.Is(modelParseError, schema.ErrUnsupportedDataType) || (stmt.Table == "" && stmt.TableExpr == nil && stmt.SQL.Len() == 0)) {
if !errors.Is(modelParseError, schema.ErrUnsupportedDataType) || stmt.Table != "" || stmt.TableExpr != nil {
_ = db.AddError(modelParseError)
}
}
}
// assign stmt.ReflectValue // assign stmt.ReflectValue
if stmt.Dest != nil { if stmt.Dest != nil {
@ -125,6 +110,11 @@ func (p *processor) Execute(db *DB) *DB {
} }
} }
// parse model again if the model has been set in scopes
if stmt.Schema == nil && (modelParseError == nil || errors.Is(modelParseError, schema.ErrUnsupportedDataType)) {
modelParseError = p.parseModelValue(db, stmt)
}
if stmt.Table == "" && stmt.TableExpr == nil && stmt.SQL.Len() == 0 { if stmt.Table == "" && stmt.TableExpr == nil && stmt.SQL.Len() == 0 {
_ = db.AddError(fmt.Errorf("%w: Table not set, please set it like: db.Model(&user) or db.Table(\"users\")", modelParseError)) _ = db.AddError(fmt.Errorf("%w: Table not set, please set it like: db.Model(&user) or db.Table(\"users\")", modelParseError))
} }
@ -151,6 +141,29 @@ func (p *processor) Execute(db *DB) *DB {
return db return db
} }
func (p *processor) parseModelValue(db *DB, stmt *Statement) error {
p.assignModelValues(stmt)
var err error
if stmt.Model != nil {
err = stmt.Parse(stmt.Model)
if err != nil && (!errors.Is(err, schema.ErrUnsupportedDataType) || (stmt.Table == "" && stmt.TableExpr == nil && stmt.SQL.Len() == 0)) {
if !errors.Is(err, schema.ErrUnsupportedDataType) || stmt.Table != "" || stmt.TableExpr != nil {
_ = db.AddError(err)
}
}
}
return err
}
func (p *processor) assignModelValues(stmt *Statement) {
if stmt.Model == nil {
stmt.Model = stmt.Dest
} else if stmt.Dest == nil {
stmt.Dest = stmt.Model
}
}
func (p *processor) Get(name string) func(*DB) { func (p *processor) Get(name string) func(*DB) {
for i := len(p.callbacks) - 1; i >= 0; i-- { for i := len(p.callbacks) - 1; i >= 0; i-- {
if v := p.callbacks[i]; v.name == name && !v.remove { if v := p.callbacks[i]; v.name == name && !v.remove {

View File

@ -49,3 +49,43 @@ func TestSchemaAccessibleFromScopes(t *testing.T) {
t.Errorf("invalid schema found, expected non-nil schema") t.Errorf("invalid schema found, expected non-nil schema")
} }
} }
func TestSetModelInScope(t *testing.T) {
users := []User{
*GetUser("model-scope-1", Config{}),
*GetUser("model-scope-2", Config{}),
}
if err := DB.Create(&users).Error; err != nil {
t.Fatalf("errors happened when create users: %v", err)
}
scope := func(db *gorm.DB) *gorm.DB {
return db.Model(&User{})
}
var results []map[string]interface{}
tx := DB.Scopes(scope)
tx = tx.Select("name", "age").Where("name like ?", "model-scope-%").Find(&results)
if err := tx.Error; err != nil {
t.Errorf("failed to query users, got error: %v", err)
}
expects := []User{
{Name: "model-scope-1", Age: 18},
{Name: "model-scope-2", Age: 18},
}
if len(results) != 2 {
t.Fatalf("invalid results length found, expects: %v, got %v", len(expects), len(results))
}
expectedTableName := "users"
if tx.Statement.Table != expectedTableName {
t.Errorf("invalid table name found, expects: %v, got %v", expectedTableName, tx.Statement.Table)
}
if tx.Statement.Schema == nil {
t.Errorf("invalid schema found, expected non-nil schema")
}
}