diff --git a/association.go b/association.go index 6a4dc600..be6b1b35 100644 --- a/association.go +++ b/association.go @@ -177,7 +177,7 @@ func (association *Association) Count() int { whereSql := fmt.Sprintf("%v.%v = ?", newScope.QuotedTableName(), relationship.ForeignKey) scope.db.Model("").Table(newScope.QuotedTableName()).Where(whereSql, association.PrimaryKey).Count(&count) } else if relationship.Kind == "belongs_to" { - if v, ok := scope.FieldValueByName(association.Column); ok { + if v, err := scope.FieldValueByName(association.Column); err == nil { whereSql := fmt.Sprintf("%v.%v = ?", newScope.QuotedTableName(), relationship.ForeignKey) scope.db.Model("").Table(newScope.QuotedTableName()).Where(whereSql, v).Count(&count) } diff --git a/scope.go b/scope.go index 4183e1c2..b91e42fd 100644 --- a/scope.go +++ b/scope.go @@ -145,7 +145,7 @@ func (scope *Scope) HasColumn(column string) bool { } // FieldValueByName to get column's value and existence -func (scope *Scope) FieldValueByName(name string) (interface{}, bool) { +func (scope *Scope) FieldValueByName(name string) (interface{}, error) { return FieldValueByName(name, scope.Value) } diff --git a/scope_private.go b/scope_private.go index e97dfce0..85c5462a 100644 --- a/scope_private.go +++ b/scope_private.go @@ -474,7 +474,7 @@ func (scope *Scope) related(value interface{}, foreignKeys ...string) *Scope { } // has one - if foreignValue, ok := scope.FieldValueByName(foreignKey); ok { + if foreignValue, err := scope.FieldValueByName(foreignKey); err == nil { toScope.inlineCondition(foreignValue).callCallbacks(scope.db.parent.callback.queries) return scope } diff --git a/utils.go b/utils.go index f4fb6625..840af20a 100644 --- a/utils.go +++ b/utils.go @@ -2,6 +2,8 @@ package gorm import ( "bytes" + "errors" + "fmt" "reflect" "strings" "sync" @@ -24,27 +26,21 @@ func (s *safeMap) Get(key string) string { return s.m[key] } -func FieldValueByName(name string, value interface{}, withAddr ...bool) (interface{}, bool) { +func FieldValueByName(name string, value interface{}) (i interface{}, err error) { data := reflect.Indirect(reflect.ValueOf(value)) name = SnakeToUpperCamel(name) if data.Kind() == reflect.Struct { if field := data.FieldByName(name); field.IsValid() { - if len(withAddr) > 0 && field.CanAddr() { - return field.Addr().Interface(), true - } else { - return field.Interface(), true - } - } - } else if data.Kind() == reflect.Slice { - elem := data.Type().Elem() - if elem.Kind() == reflect.Ptr { - return nil, reflect.New(data.Type().Elem().Elem()).Elem().FieldByName(name).IsValid() + i = field.Interface() } else { - return nil, reflect.New(data.Type().Elem()).Elem().FieldByName(name).IsValid() + return nil, errors.New(fmt.Sprintf("struct has no field with name %s", name)) } + } else { + return nil, errors.New("value must be of kind struct") } - return nil, false + + return } func newSafeMap() *safeMap {