mirror of
https://github.com/ent/ent.git
synced 2026-05-24 09:31:56 +03:00
doc/faq: add examples how to extend the generated builders (#1335)
This commit is contained in:
@@ -15,7 +15,9 @@ sidebar_label: FAQ
|
||||
[How to customize time fields to type `DATETIME` in MySQL?](#how-to-customize-time-fields-to-type-datetime-in-mysql) \
|
||||
[How to use a custom generator of IDs?](#how-to-use-a-custom-generator-of-ids) \
|
||||
[How to define a spatial data type field in MySQL?](#how-to-define-a-spatial-data-type-field-in-mysql) \
|
||||
[How to define custom types in external templates?](#how-to-define-custom-types-in-external-templates)
|
||||
[How to extend the generated models?](#how-to-extend-the-generated-models) \
|
||||
[How to extend the generated builders?](#how-to-extend-the-generated-builders)
|
||||
|
||||
## Answers
|
||||
|
||||
#### How to create an entity from a struct `T`?
|
||||
@@ -464,29 +466,70 @@ func (Point) SchemaType() map[string]string {
|
||||
|
||||
A full example exists in the [example repository](https://github.com/a8m/entspatial).
|
||||
|
||||
#### How to define custom types in external templates?
|
||||
We can extend ent generated types with additional fields by defining a template called **model/fields/additional** like in this [example](https://github.com/ent/ent/blob/3ee6621194709db97e53f8ee6888593e156acc5e/examples/entcpkg/ent/template/static.tmpl). And sometimes we want to define these additional fields with our own types then we need to add the following template definitions also:
|
||||
```
|
||||
{{- define "import/additional/field_types" }}
|
||||
|
||||
#### How to extend the generated models?
|
||||
|
||||
Ent supports extending generated types (both global types and models) using custom templates. For example, in order to
|
||||
add additional struct fields or methods to the generated model, we can override the `model/fields/additional` template like in this
|
||||
[example](https://github.com/ent/ent/blob/dd4792f5b30bdd2db0d9a593a977a54cb3f0c1ce/examples/entcpkg/ent/template/static.tmpl).
|
||||
|
||||
|
||||
If your custom fields/methods require additional imports, you can add those imports using custom templates as well:
|
||||
|
||||
```gotemplate
|
||||
{{- define "import/additional/field_types" -}}
|
||||
"github.com/path/to/your/custom/type"
|
||||
{{- end -}}
|
||||
|
||||
{{- define "import/additional/client_dependencies" }}
|
||||
{{- define "import/additional/client_dependencies" -}}
|
||||
"github.com/path/to/your/custom/type"
|
||||
{{- end -}}
|
||||
```
|
||||
|
||||
Full example:
|
||||
```
|
||||
{{- define "import/additional/user_types" }}
|
||||
"github.com/path/to/your/groupcount/type"
|
||||
{{- end -}}
|
||||
#### How to extend the generated builders?
|
||||
|
||||
{{ define "model/fields/additional" }}
|
||||
{{- if eq $.Name "User" }}
|
||||
// StaticField defined by template.
|
||||
GroupsCount []Groupcount `json:"groups_count,omitempty"`
|
||||
{{- end }}
|
||||
In case you want to extend the generated client and add dependencies to all different builders under the `ent` package,
|
||||
you can use the `"config/{fields,options}/*"` templates as follows:
|
||||
|
||||
```gotemplate
|
||||
{{/* A template for adding additional config fields/options. */}}
|
||||
{{ define "config/fields/httpclient" -}}
|
||||
// HTTPClient field added by a test template.
|
||||
HTTPClient *http.Client
|
||||
{{ end }}
|
||||
|
||||
{{ define "config/options/httpclient" }}
|
||||
// HTTPClient option added by a test template.
|
||||
func HTTPClient(hc *http.Client) Option {
|
||||
return func(c *config) {
|
||||
c.HTTPClient = hc
|
||||
}
|
||||
}
|
||||
{{ end }}
|
||||
```
|
||||
**Note:** Additional import template definitions must start with **import/additional/**.
|
||||
|
||||
Then, you can inject this new dependency to your client, and access it in all builders:
|
||||
|
||||
```go
|
||||
func main() {
|
||||
client, err := ent.Open(
|
||||
"sqlite3",
|
||||
"file:ent?mode=memory&cache=shared&_fk=1",
|
||||
// Custom config option.
|
||||
ent.HTTPClient(http.DefaultClient),
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer client.Close()
|
||||
ctx := context.Background()
|
||||
client.User.Use(func(next ent.Mutator) ent.Mutator {
|
||||
return hook.UserFunc(func(ctx context.Context, m *ent.UserMutation) (ent.Value, error) {
|
||||
// Access the injected HTTP client here.
|
||||
_ = m.HTTPClient
|
||||
return next.Mutate(ctx, m)
|
||||
})
|
||||
})
|
||||
// ...
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user