Files
ent/doc/md/schema-fields.md
Ariel Mashraki a79c1c20c0 ent/doc: update field docs
Reviewed By: alexsn

Differential Revision: D17074006

fbshipit-source-id: e69c09a5db12b6b59ad6fb00fb47362eb4ab2863
2019-08-27 10:23:26 -07:00

5.8 KiB
Executable File

id, title
id title
schema-fields Fields

Quick Summary

Fields (or properties) in the schema are the attributes of the vertex. For example, a User with 4 fields: age, name, username and created_at:

re-fields-properties

Fields are returned from the schema using the Fields method. For example:

package schema

import (
	"time"

	"github.com/facebookincubator/ent"
	"github.com/facebookincubator/ent/schema/field"
)

// User schema.
type User struct {
	ent.Schema
}

// Fields of the user.
func (User) Fields() []ent.Field {
	return []ent.Field{
		field.Int("age"),
		field.String("name"),
		field.String("username").
			Unique(),
		field.Time("created_at").
			Default(time.Now),
	}
}

All fields are required by default, and can be set to optional using the Optional method.

Types

The following types are currently supported by the framework:

  • All Go numeric types. Like, int, uint8, float64, etc.
  • bool
  • string
  • time.Time
  • []byte (only support by SQL dialects).
package schema

import (
	"time"

	"github.com/facebookincubator/ent"
	"github.com/facebookincubator/ent/schema/field"
)

// User schema.
type User struct {
	ent.Schema
}

// Fields of the user.
func (User) Fields() []ent.Field {
	return []ent.Field{
		field.Int("age").
			Positive(),
		field.Float("rank").
			Optional(),
		field.Bool("active").
			Default(false),
		field.String("name").
			Unique(),
		field.Time("created_at").
			Default(time.Now),
	}
}

To read more about how each type is mapped to its database-type, go to the Migration section.

Default Values

Non-unique fields support default values using the .Default and .UpdateDefault methods.

// Fields of the User.
func (User) Fields() []ent.Field {
	return []ent.Field{
		field.Time("created_at").
			Default(time.Now),
		field.Time("updated_at").
			Default(time.Now).
			UpdateDefault(time.Now),
	}
}

Validators

A field validator is a function from type func(T) error that is defined in the schema using the Validate method, and applied on the given field value before creating or updating the entity.

The supported types for field validators are string and all numeric types.

package schema

import (
	"errors"
	"regexp"
	"strings"
	"time"

	"github.com/facebookincubator/ent"
	"github.com/facebookincubator/ent/schema/field"
)


// Group schema.
type Group struct {
	ent.Schema
}

// Fields of the group.
func (Group) Fields() []ent.Field {
	return []ent.Field{
		field.String("name").
			Match(regexp.MustCompile("[a-zA-Z_]+$")).
			Validate(func(s string) error {
				if strings.ToLower(s) == s {
					return errors.New("group name must begin with uppercase")
				}
				return nil
			}),
	}
}

Builtin Validators

The framework provides a few builtin validators for each type:

  • Numeric types:

    • Positive()
    • Negative()
    • Min(i) - Validate that the given value is > i.
    • Max(i) - Validate that the given value is < i.
    • Range(i, j) - Validate that the given value is within the range [i, j].
  • string

    • MinLen(i)
    • MaxLen(i)
    • Match(regexp.Regexp)

Optional

Optional fields are fields that are not required in the entity creation, and will be set to nullable fields in the database. Unlike edges, fields are required by default, and setting them to optional should be done explicitly using the Optional method.

// Fields of the user.
func (User) Fields() []ent.Field {
	return []ent.Field{
		field.String("required_name"),
		field.String("optional_name").
			Optional(),
	}
}

Nillable

Sometime, you want to be able to distinguish between the zero value of fields and nil. For example, if the database column contains 0 or NULL. The Nillable option exists exactly for this.

If you have an Optional field of type T, setting it to Nillable will generate a struct field with type *T. Hence, if the database returns NULL for this field, the struct field will be nil. Otherwise, it will contains a pointer to the actual data.

For example, given this schema:

// Fields of the user.
func (User) Fields() []ent.Field {
	return []ent.Field{
		field.String("required_name"),
		field.String("optional_name").
			Optional(),
		field.String("nillable_name").
			Optional().
			Nillable(),
	}
}

The generated struct for the User entity will be as follows:

// ent/user.go
package ent

// User entity.
type User struct {
	RequiredName string `json:"required_name,omitempty"`
	OptionalName string `json:"optional_name,omitempty"`
	NillableName string `json:"nillable_name,omitempty"`
}

Immutable

Immutable fields are fields that can be set only in the creation of the entity. i.e., no setters will be generated for the entity updater.

// Fields of the user.
func (User) Fields() []ent.Field {
	return []ent.Field{
		field.String("name"),
		field.Time("created_at").
			Default(time.Now),
			Immutable(),
	}
}

Uniqueness

Fields can be defined as unique using the Unique method. Note that, unique fields cannot have default values.

// Fields of the user.
func (User) Fields() []ent.Field {
	return []ent.Field{
		field.String("name"),
		field.String("nickname").
			Unique(),
	}
}

Indexes

Indexes can be defined on multi fields and some types of edges as well. However, you should note, that this is currently an SQL-only feature.

Read more about this in the Indexes section.

Struct Tags

Custom struct tags can be added to the generated entities using the StructTag method. Note that, if this option was not provided, or provided and did not contain the json tag, the default json tag will be added with the field name.

// Fields of the user.
func (User) Fields() []ent.Field {
	return []ent.Field{
		field.String("name").
			StructTag(`gqlgen:"gql_name"`),
	}
}