Pg: Auto set time for "update_at" / "create_at" if exists?

Created on 16 Aug 2017  路  6Comments  路  Source: go-pg/pg

Is there anyway to auto set time if there are a timestamp column named "updated_at", "created_at" or "UpdatedAt", "CreatedAt" on the struct.

What did you guys do?

Most helpful comment

@kieusonlam You can define a base model, and customize it when needed.

type BaseModel struct {
    ID        int64
    CreatedAt time.Time
    UpdatedAt time.Time
    DeletedAt *time.Time
}

func (m *BaseModel) BeforeInsert(db orm.DB) error {
    now := time.Now()
    if m.CreatedAt.IsZero() {
        m.CreatedAt = now
    }
    if m.UpdatedAt.IsZero() {
        m.UpdatedAt = now
    }
    return nil
}

func (m *BaseModel) BeforeUpdate(db orm.DB) error {
    m.UpdatedAt = time.Now()
    return nil
}

// user has no other hooks
type User struct {
    BaseModel

    Username string
}

// admin has more hooks
type Admin struct {
    BaseModel

    LastSigninAt time.Time
}

func (a *Admin) BeforeInsert(db orm.DB) error {
    if err := a.BaseModel.BeforeInsert(db); err != nil {
        return err
    }

    if a.LastSigninAt.IsZero() {
        a.LastSigninAt = time.Now()
    }
    return nil
}

All 6 comments

Why not to use PostgreSQL defaults? https://www.postgresql.org/docs/9.6/static/ddl-default.html

Another way is to use hook:

func (b *Book) BeforeInsert(db orm.DB) error {
    if b.CreatedAt.IsZero() {
        b.CreatedAt = time.Now()
    }
    return nil
}

@vmihailenco if we have a lot of table, we have to do it for every single one :( I think it's inconvenient.

@kieusonlam You can define a base model, and customize it when needed.

type BaseModel struct {
    ID        int64
    CreatedAt time.Time
    UpdatedAt time.Time
    DeletedAt *time.Time
}

func (m *BaseModel) BeforeInsert(db orm.DB) error {
    now := time.Now()
    if m.CreatedAt.IsZero() {
        m.CreatedAt = now
    }
    if m.UpdatedAt.IsZero() {
        m.UpdatedAt = now
    }
    return nil
}

func (m *BaseModel) BeforeUpdate(db orm.DB) error {
    m.UpdatedAt = time.Now()
    return nil
}

// user has no other hooks
type User struct {
    BaseModel

    Username string
}

// admin has more hooks
type Admin struct {
    BaseModel

    LastSigninAt time.Time
}

func (a *Admin) BeforeInsert(db orm.DB) error {
    if err := a.BaseModel.BeforeInsert(db); err != nil {
        return err
    }

    if a.LastSigninAt.IsZero() {
        a.LastSigninAt = time.Now()
    }
    return nil
}

@siteshen Thanks. This is perfect.

Hi, I am new here. Can anyone please tell me how BeforeInsert and BeforeUpdate get called? I tried a similar code, but they are not called automatically. Thanks a lot.

I have asked the question at https://github.com/go-pg/pg/issues/1323 in more detail context and code. Sorry for the interruption.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

bobobo1618 picture bobobo1618  路  3Comments

m-kad picture m-kad  路  3Comments

Alireza-Ta picture Alireza-Ta  路  3Comments

RepentantGopher picture RepentantGopher  路  5Comments

mamal72 picture mamal72  路  3Comments