Search code examples
mgogorilla

gorilla/schema and mgo/bson.ObjectId


Here's a bit of a chicken and egg problem.

In a HTML template, a form, bson.ObjectId needs to be rendered with {{mytype.Id.Hex()}}

e.g.

<form method="post">
<input name="id" value="{{mytype.Id.Hex()}}>
</form>

In Go when defining a struct that is supposed to be parsed by gorilla/schema

type MyType struct {
    Id bson.ObjectId `bson:"_id,omitempty" schema:"id"`
}

when you call (from schema) decoder.Decode(instance_of_mytype, r.PostForm) it "throws" an error: schema: invalid path "id" since the format is just the string respresentation of bson.ObjectId and not an actual bson.ObjectId.

I wonder what I could do except filling the fields manually (r.FormValue()) to make it work.

Should I create an issue with gorilla/schema or mgo or should I just do it manually?


Solution

  • You might define your own string-based type which holds the hex representation of the value, and implement the bson.Getter and bson.Setter interfaces on it. Gorilla will ignore these interfaces and use the string value, and bson will ignore the string value and use the interface.

    Something along these lines (untested code):

    type hexId string
    
    func (id hexId) GetBSON() (interface{}, error) {
            return bson.ObjectIdHex(string(id)), nil
    }
    
    func (id *hexId) SetBSON(raw bson.Raw) error {
            var objId bson.ObjectId
            err := raw.Unmarshal(&objId)
            if err != nil {
                    return err
            }
            *id = hexId(objId.Hex())
            return nil
    }