src-d/go-kallax

Detach 1:1 relationship record

ligustah opened this issue · 1 comments

Hello,

I have a model A that contains an optional inverse 1:1 relationship to model B like this:

type A struct {
	kallax.Model
	ID    int64 `pk:"autoincr"`
	B     *B `fk:",inverse"`
}

type B struct {
	kallax.Model
	ID        int64 `pk:"autoincr"`
}

However, I don't seem to find a builtin way of removing this relationship from model A (i.e. set the virtual column to NULL). When I set the value for B on the model struct of A to nil it is just ignored. From looking at the code this appears to be, because the virtual column is never modified if B is nil. Since it still holds the value that was queried it'll just set the foreign key to what it was before. Calling ClearVirtualColumns on the model removes the previous value, but also causes it to be ignored on the update call.
After some tinkering I did find a workaround that allows me to properly clear the column, but I feel this should somehow be handled by kallax, because the workaround relies on the AddVirtualColumn method, which is supposed to be used for internal purposes only. It's just some glue code around using the stdlib sql.NullInt64 as a kallax.Identifier in the call to AddVirtualColumn.

type NullableNumericID sql.NullInt64

func (id *NullableNumericID) Scan(value interface{}) error {
	return (*sql.NullInt64)(id).Scan(value)
}

func (id NullableNumericID) Value() (driver.Value, error) {
	return (sql.NullInt64)(id).Value()
}

func (id NullableNumericID) IsEmpty() bool {
	return !sql.NullInt64(id).Valid
}

func (id NullableNumericID) String() string {
	return fmt.Sprint((sql.NullInt64)(id).Int64)
}

func (id NullableNumericID) Equals(other kallax.Identifier) bool {
	v, ok := other.(*NullableNumericID)
	if !ok {
		return false
	}

	// ignoring the Valid field here for now
	return (sql.NullInt64)(id).Int64 == (sql.NullInt64)(*v).Int64
}

func (id NullableNumericID) Raw() interface{} {
	return id
}

// using it like this

a.AddVirtualColumn("b_id", &models.NullableNumericID{
	Valid: false,
})

Is there a chance for kallax to support this use-case natively?

Kallax is unable to do this at the moment, but it is definitely high up on my task list. This has been mentioned before (#219), but again it's something that conflicts directly with the n:m relationship management. It will be implemented right after n:m relationships.

I'm closing this as dupe, please continue discussing this matter on #219.