Documentation
¶
Overview ¶
Package fields, admin panel için alan (field) tanımlamalarını sağlar.
Bu dosya, core paketinden type alias'ları içe aktarır ve fields paketinde kullanılabilir hale getirir. Bu sayede fields paketi, core paketine doğrudan bağımlı olmadan temel tipleri kullanabilir.
Alan Bağımlılık Çözücü Paketi ¶
Bu paket, form alanları arasındaki bağımlılıkları yönetir ve çözer. Bir alanın değeri değiştiğinde, ona bağımlı diğer alanların otomatik olarak güncellenmesini sağlar.
## Temel Özellikler
- **Bağımlılık Grafiği**: Alanlar arası bağımlılık ilişkilerini graf yapısında tutar - **Otomatik Güncelleme**: Değişen alanlara bağlı tüm alanları otomatik günceller - **Döngüsel Bağımlılık Tespiti**: Sonsuz döngülere neden olabilecek bağımlılıkları tespit eder - **BFS/DFS Algoritmaları**: Etkin graf traversal algoritmaları kullanır
## Kullanım Senaryoları
1. **Cascade Seçimler**: Ülke seçildiğinde şehir listesinin güncellenmesi 2. **Koşullu Alanlar**: Bir checkbox işaretlendiğinde ilgili alanların gösterilmesi 3. **Dinamik Validasyon**: Bir alanın değerine göre diğer alanların validasyon kurallarının değişmesi 4. **Hesaplanan Alanlar**: Birden fazla alanın değerine göre otomatik hesaplama yapılması
## Örnek Kullanım
```go // Bağımlılık çözücü oluştur resolver := NewDependencyResolver(fields, "form")
// Döngüsel bağımlılık kontrolü
if err := resolver.DetectCircularDependencies(); err != nil {
log.Fatal(err)
}
// Değişen alanlar için bağımlılıkları çöz updates, err := resolver.ResolveDependencies(formData, []string{"country"}, ctx)
if err != nil {
log.Fatal(err)
}
```
Package fields, admin panel için alan (field) tanımlamalarını sağlar.
Bu dosya, core paketinden type alias'ları ve constant'ları içe aktarır. Bu sayede fields paketi, core paketine doğrudan bağımlı olmadan temel tipleri kullanabilir.
Package fields, alan davranışlarını birleştirilebilir hale getiren mixin'leri sağlar.
Bu paket, alanlara modüler işlevsellik eklemek için mixin pattern (kompozisyon) uygular. Her mixin, alan türlerine gömülebilen belirli bir yetenek sağlar.
Mevcut Mixin'ler ¶
- Searchable: Alanların özel arama mantığı ile aranabilir olmasını sağlar - Sortable: Alanların özel sıralama mantığı ile sıralanabilir olmasını sağlar - Filterable: Alanların özel filtreleme mantığı ile filtrelenebilir olmasını sağlar - Validatable: Alanların doğrulama kuralları ve özel doğrulayıcılara sahip olmasını sağlar - Displayable: Alanların görüntüleme formatını özelleştirmesini sağlar - Hideable: Alanların farklı bağlamlarda görünürlüğünü kontrol etmesini sağlar
Kullanım Örneği ¶
type CustomField struct {
fields.Base
fields.Searchable
fields.Sortable
}
field := &CustomField{}
field.SetSearchableColumns([]string{"name", "email"})
field.SetSortable(true)
Mimari ¶
Mixin'ler, Go Panel API mimarisinde önerilen kompozisyon pattern'ini takip eder. Kalıtım olmadan yeniden kullanılabilir işlevsellik sağlarlar, bu da tek bir alan türünde birden fazla yeteneği birleştirmeyi kolaylaştırır.
Daha fazla bilgi için docs/Fields.md ve .docs/ARCHITECTURE.md dosyalarına bakın.
Package fields, veritabanı ilişkilerini alan sisteminde temsil eden yapıları sağlar.
Bu dosya, ilişki alanlarının (BelongsTo, HasMany, HasOne, BelongsToMany, MorphTo) temel interface'lerini ve tiplerini tanımlar.
İlişki Türleri ¶
- **BelongsTo**: Ters one-to-one veya one-to-many ilişki (bir Post bir Author'a aittir) - **HasMany**: One-to-many ilişki (bir Author birden fazla Post'a sahiptir) - **HasOne**: One-to-one ilişki (bir User bir Profile'a sahiptir) - **BelongsToMany**: Many-to-many ilişki (bir User birden fazla Role'e sahiptir) - **MorphTo**: Polimorfik ilişki (bir Comment farklı tiplere ait olabilir)
Yükleme Stratejileri ¶
- **Eager Loading**: N+1 sorgu problemini önler, ilişkili verileri önceden yükler - **Lazy Loading**: İhtiyaç anında yükler, bellek tasarrufu sağlar
Kullanım Örneği ¶
// BelongsTo ilişkisi
field := fields.NewBelongsTo("Author", "author_id", "authors").
DisplayUsing("name").
WithSearchableColumns("name", "email").
WithEagerLoad()
// HasMany ilişkisi
field := fields.NewHasMany("Posts", "posts", "posts").
ForeignKey("author_id").
WithEagerLoad()
Daha fazla bilgi için docs/Relationships.md ve .docs/RESOURCE_BASED_RELATIONSHIPS.md dosyalarına bakın.
Package fields, ilişkisel alanlar için kısıtlama (constraint) yönetimi sağlar.
Bu paket, relationship field'ları üzerinde sorgu kısıtlamaları uygulamak için gerekli interface ve implementasyonları içerir. LIMIT, OFFSET, WHERE ve WHERE IN gibi SQL kısıtlamalarını yönetir.
Referans ¶
Detaylı kullanım ve örnekler için: docs/Relationships.md(../../docs/Relationships.md)
Package fields, ilişkisel veritabanı alanları için sayma (counting) işlevselliği sağlar.
Bu paket, farklı ilişki türleri (BelongsTo, HasMany, HasOne, BelongsToMany, MorphTo) için ilişkili kaynak sayılarını hesaplamak üzere tasarlanmıştır.
Desteklenen İlişki Türleri ¶
- `belongsTo`: 0 veya 1 döner (tekil ilişki) - `hasOne`: 0 veya 1 döner (tekil ilişki) - `hasMany`: İlişkili kaynak sayısını döner (çoğul ilişki) - `belongsToMany`: Pivot tablo kayıt sayısını döner (çoktan-çoğa ilişki) - `morphTo`: 0 veya 1 döner (polimorfik ilişki)
Referanslar ¶
Detaylı ilişki dokümantasyonu için: `docs/Relationships.md`
Package fields, ilişkisel veritabanı alanları için varlık kontrolü işlevselliği sağlar.
Bu paket, relationship field'ların ilişkili kaynaklarının var olup olmadığını kontrol etmek için kullanılan interface ve implementasyonları içerir.
Desteklenen İlişki Tipleri ¶
- `belongsTo`: Ters bire-bir veya bire-çok ilişki - `hasMany`: Bire-çok ilişki - `hasOne`: Bire-bir ilişki - `belongsToMany`: Çoka-çok ilişki (pivot tablo üzerinden) - `morphTo`: Polimorfik ilişki
Referans ¶
Detaylı bilgi için bkz: `docs/Relationships.md`
Package fields, ilişkisel veritabanı alanları ve sayfalama işlevselliği sağlar.
Bu paket, ilişkili kayıtlar için sayfalama yönetimi ve metadata işlemlerini içerir. Sayfa numarası, sayfa boyutu ve toplam kayıt sayısı gibi bilgileri yönetir.
Daha fazla bilgi için docs/Relationships.md dosyasına bakın.
Package fields, ilişki serileştirme işlemlerini yönetir.
Bu paket, relationship field'larının JSON formatına dönüştürülmesi için gerekli interface ve implementasyonları sağlar.
Referans ¶
Detaylı bilgi için: docs/Relationships.md(../../docs/Relationships.md)
Package fields, ilişkisel alan (relationship field) doğrulama işlemlerini yönetir.
Bu paket, veritabanı ilişkilerinin (BelongsTo, HasMany, HasOne, BelongsToMany, MorphTo) doğrulanması için gerekli validator implementasyonlarını sağlar.
İlişki Tipleri ¶
- **BelongsTo**: Bir kaydın başka bir kayda ait olduğu ilişki - **HasMany**: Bir kaydın birden fazla ilişkili kayda sahip olduğu ilişki - **HasOne**: Bir kaydın tek bir ilişkili kayda sahip olduğu ilişki - **BelongsToMany**: Çoka-çok ilişki (pivot tablo ile) - **MorphTo**: Polimorfik ilişki (birden fazla model tipine bağlanabilir)
Referans ¶
Detaylı ilişki dokümantasyonu için: `docs/Relationships.md`
Örnek Kullanım ¶
```go validator := fields.NewRelationshipValidator()
// BelongsTo ilişkisini doğrula err := validator.ValidateBelongsTo(ctx, userID, belongsToField)
if err != nil {
log.Printf("İlişki doğrulama hatası: %v", err)
}
// MorphTo ilişkisini doğrula err = validator.ValidateMorphTo(ctx, morphValue, morphToField)
if err != nil {
log.Printf("Polimorfik ilişki hatası: %v", err)
}
```
Package fields, test senaryoları için yardımcı fonksiyonlar ve yapılar sağlar.
Bu paket, field sisteminin test edilmesi için gerekli olan veritabanı bağlantıları, test verileri ve model yapılarını içerir. SQLite in-memory veritabanı kullanarak hızlı ve izole test ortamları oluşturur.
Temel Özellikler ¶
- In-memory SQLite veritabanı desteği - Otomatik tablo oluşturma ve veri doldurma - İlişkisel veri modelleri (HasOne, HasMany, BelongsTo, BelongsToMany, MorphTo) - Test için hazır örnek veriler
Kullanım Senaryoları ¶
- Unit testlerde veritabanı bağlantısı gerektiğinde - İlişkisel sorguların test edilmesinde - Field sisteminin entegrasyon testlerinde - Performans testlerinde tutarlı veri seti oluşturmada
Örnek Kullanım ¶
```go
func TestMyFeature(t *testing.T) {
// Test veritabanı oluştur
testDB := NewTestDB(t)
defer testDB.Close()
// Veritabanını kullan
var users []User
testDB.DB.Query("SELECT * FROM users")
}
```
Package fields, admin panel için alan (field) tanımlamalarını sağlar.
Bu dosya, alan doğrulama (validation) sistemini içerir. Alanlar için çeşitli doğrulama kuralları tanımlanabilir ve bu kurallar form gönderildiğinde otomatik olarak çalıştırılır.
Index ¶
- Variables
- func ApplyConditionalValidation(validator ConditionalValidator, value interface{}, context interface{}) error
- func ApplyCustomValidator(name string, value interface{}, context interface{}) error
- func ApplyValidationRule(rule ValidationRule, value interface{}) error
- func GetTestDataDir() string
- func RegisterCustomValidator(name string, validator ValidatorFunc)
- func ValidateEmail(value interface{}) error
- func ValidateMax(value interface{}, max interface{}) error
- func ValidateMaxLength(value interface{}, length int) error
- func ValidateMin(value interface{}, min interface{}) error
- func ValidateMinLength(value interface{}, length int) error
- func ValidatePattern(value interface{}, pattern string) error
- func ValidateRequired(value interface{}) error
- func ValidateURL(value interface{}) error
- type BelongsToField
- func (b *BelongsToField) AutoOptions(displayField string) *BelongsToField
- func (b *BelongsToField) DisplayUsing(key string) *BelongsToField
- func (b *BelongsToField) Extract(record any)
- func (b *BelongsToField) GetDisplayKey() string
- func (b *BelongsToField) GetForeignKey() string
- func (b *BelongsToField) GetHoverCard() *HoverCardConfig
- func (b *BelongsToField) GetLoadingStrategy() LoadingStrategy
- func (b *BelongsToField) GetOwnerKeyColumn() string
- func (b *BelongsToField) GetQueryCallback() func(interface{}) interface{}
- func (b *BelongsToField) GetRelatedResource() string
- func (b *BelongsToField) GetRelatedResourceSlug() string
- func (b *BelongsToField) GetRelatedTableName() string
- func (b *BelongsToField) GetRelationshipName() string
- func (b *BelongsToField) GetRelationshipType() string
- func (b *BelongsToField) GetSearchableColumns() []string
- func (b *BelongsToField) GetTypes() map[string]string
- func (b *BelongsToField) HoverCard(hoverStruct interface{}) *BelongsToField
- func (b *BelongsToField) IsRequired() bool
- func (b *BelongsToField) Query(fn func(interface{}) interface{}) *BelongsToField
- func (b *BelongsToField) ResolveHoverCard(resolver HoverCardResolver) *BelongsToField
- func (b *BelongsToField) ResolveRelationship(item interface{}) (interface{}, error)
- func (b *BelongsToField) Searchable() Element
- func (b *BelongsToField) ValidateRelationship(value interface{}) error
- func (b *BelongsToField) WithEagerLoad() *BelongsToField
- func (b *BelongsToField) WithHoverCard(config HoverCardConfig) *BelongsToField
- func (b *BelongsToField) WithLazyLoad() *BelongsToField
- func (b *BelongsToField) WithSearchableColumns(columns ...string) *BelongsToField
- type BelongsToManyField
- func (b *BelongsToManyField) AutoOptions(displayField string) *BelongsToManyField
- func (b *BelongsToManyField) Count() int64
- func (b *BelongsToManyField) Extract(resource interface{})
- func (b *BelongsToManyField) ForeignKey(key string) *BelongsToManyField
- func (b *BelongsToManyField) GetDisplayKey() string
- func (b *BelongsToManyField) GetLoadingStrategy() LoadingStrategy
- func (b *BelongsToManyField) GetQueryCallback() func(interface{}) interface{}
- func (b *BelongsToManyField) GetRelatedResourceSlug() string
- func (b *BelongsToManyField) GetRelationshipName() string
- func (b *BelongsToManyField) GetRelationshipType() string
- func (b *BelongsToManyField) GetSearchableColumns() []string
- func (b *BelongsToManyField) GetTypes() map[string]string
- func (b *BelongsToManyField) IsRequired() bool
- func (b *BelongsToManyField) PivotTable(table string) *BelongsToManyField
- func (b *BelongsToManyField) Query(fn func(interface{}) interface{}) *BelongsToManyField
- func (b *BelongsToManyField) RelatedKey(key string) *BelongsToManyField
- func (b *BelongsToManyField) ResolveRelationship(item interface{}) (interface{}, error)
- func (b *BelongsToManyField) Searchable() Element
- func (b *BelongsToManyField) ValidateRelationship(value interface{}) error
- func (b *BelongsToManyField) WithEagerLoad() *BelongsToManyField
- func (b *BelongsToManyField) WithLazyLoad() *BelongsToManyField
- type Comment
- type ConditionalValidator
- type Currency
- type CustomValidatorRegistry
- type DependencyCallbackFunc
- type DependencyResolver
- type DialogContentType
- type DialogField
- func (f *DialogField) Content(fields []core.Element) *DialogField
- func (f *DialogField) DefaultOpen(open bool) *DialogField
- func (f *DialogField) DialogDesc(desc string) *DialogField
- func (f *DialogField) DialogSize(size string) *DialogField
- func (f *DialogField) DialogTitle(title string) *DialogField
- func (f *DialogField) Extract(resource interface{})
- func (f *DialogField) GetContext() ElementContext
- func (f *DialogField) GetKey() string
- func (f *DialogField) GetView() string
- func (f *DialogField) JsonSerialize() map[string]any
- func (f *DialogField) OnComplete(fn func(ctx *fiber.Ctx, data map[string]any) error) *DialogField
- func (f *DialogField) OnSkip(fn func(ctx *fiber.Ctx) error) *DialogField
- func (f *DialogField) TriggerButton(text string) *DialogField
- func (f *DialogField) TriggerIcon(icon string) *DialogField
- func (f *DialogField) Wizard(steps []DialogStep) *DialogField
- type DialogStep
- type Displayable
- type Element
- type ElementContext
- type ElementType
- type FieldUpdate
- func (u *FieldUpdate) AddRule(rule ValidationRule) *FieldUpdate
- func (u *FieldUpdate) Disable() *FieldUpdate
- func (u *FieldUpdate) Enable() *FieldUpdate
- func (u *FieldUpdate) Hide() *FieldUpdate
- func (u *FieldUpdate) MakeEditable() *FieldUpdate
- func (u *FieldUpdate) MakeOptional() *FieldUpdate
- func (u *FieldUpdate) MakeReadOnly() *FieldUpdate
- func (u *FieldUpdate) MakeRequired() *FieldUpdate
- func (u *FieldUpdate) SetHelpText(text string) *FieldUpdate
- func (u *FieldUpdate) SetOptions(options map[string]interface{}) *FieldUpdate
- func (u *FieldUpdate) SetPlaceholder(text string) *FieldUpdate
- func (u *FieldUpdate) SetRules(rules []ValidationRule) *FieldUpdate
- func (u *FieldUpdate) SetValue(value interface{}) *FieldUpdate
- func (u *FieldUpdate) Show() *FieldUpdate
- type Filterable
- func (f *Filterable) GetFilterCallback() func(*gorm.DB, any) *gorm.DB
- func (f *Filterable) GetFilterOptions() map[string]string
- func (f *Filterable) IsFilterable() bool
- func (f *Filterable) SetFilterCallback(cb func(*gorm.DB, any) *gorm.DB)
- func (f *Filterable) SetFilterOptions(options map[string]string)
- func (f *Filterable) SetFilterable(filterable bool)
- type GormConfig
- func (g *GormConfig) ToGormTag() string
- func (g *GormConfig) WithAutoIncrement() *GormConfig
- func (g *GormConfig) WithColumn(name string) *GormConfig
- func (g *GormConfig) WithComment(comment string) *GormConfig
- func (g *GormConfig) WithDefault(value interface{}) *GormConfig
- func (g *GormConfig) WithForeignKey(fk, references string) *GormConfig
- func (g *GormConfig) WithFullTextIndex(name ...string) *GormConfig
- func (g *GormConfig) WithIDType(idType string) *GormConfig
- func (g *GormConfig) WithIndex(name ...string) *GormConfig
- func (g *GormConfig) WithManyToMany(tableName string) *GormConfig
- func (g *GormConfig) WithNotNull() *GormConfig
- func (g *GormConfig) WithOnDelete(action string) *GormConfig
- func (g *GormConfig) WithOnUpdate(action string) *GormConfig
- func (g *GormConfig) WithPrecision(precision, scale int) *GormConfig
- func (g *GormConfig) WithPrimaryKey() *GormConfig
- func (g *GormConfig) WithSize(size int) *GormConfig
- func (g *GormConfig) WithSnowflake() *GormConfig
- func (g *GormConfig) WithSoftDelete() *GormConfig
- func (g *GormConfig) WithType(sqlType string) *GormConfig
- func (g *GormConfig) WithULID() *GormConfig
- func (g *GormConfig) WithUUID() *GormConfig
- func (g *GormConfig) WithUniqueIndex(name ...string) *GormConfig
- type HasManyField
- func (h *HasManyField) AutoOptions(displayField string) *HasManyField
- func (h *HasManyField) Count() int64
- func (h *HasManyField) Extract(resource interface{})
- func (h *HasManyField) ForeignKey(key string) *HasManyField
- func (h *HasManyField) GetDisplayKey() string
- func (h *HasManyField) GetForeignKeyColumn() string
- func (h *HasManyField) GetLoadingStrategy() LoadingStrategy
- func (h *HasManyField) GetOwnerKeyColumn() string
- func (h *HasManyField) GetQueryCallback() func(interface{}) interface{}
- func (h *HasManyField) GetRelatedResource() interface{}
- func (h *HasManyField) GetRelatedResourceSlug() string
- func (h *HasManyField) GetRelatedTableName() string
- func (h *HasManyField) GetRelationshipName() string
- func (h *HasManyField) GetRelationshipType() string
- func (h *HasManyField) GetSearchableColumns() []string
- func (h *HasManyField) GetTypes() map[string]string
- func (h *HasManyField) IsRequired() bool
- func (h *HasManyField) Label(label string) Element
- func (h *HasManyField) OwnerKey(key string) *HasManyField
- func (h *HasManyField) Placeholder(placeholder string) Element
- func (h *HasManyField) Query(fn func(interface{}) interface{}) *HasManyField
- func (h *HasManyField) ResolveRelationship(item interface{}) (interface{}, error)
- func (h *HasManyField) Searchable() Element
- func (h *HasManyField) SetRelatedResource(res interface{}) *HasManyField
- func (h *HasManyField) ValidateRelationship(value interface{}) error
- func (h *HasManyField) WithEagerLoad() *HasManyField
- func (h *HasManyField) WithFullData() *HasManyField
- func (h *HasManyField) WithLazyLoad() *HasManyField
- type HasOneField
- func (h *HasOneField) AutoOptions(displayField string) *HasOneField
- func (h *HasOneField) Extract(resource interface{})
- func (h *HasOneField) ForeignKey(key string) *HasOneField
- func (h *HasOneField) GetDisplayKey() string
- func (h *HasOneField) GetForeignKeyColumn() string
- func (h *HasOneField) GetHoverCard() *HoverCardConfig
- func (h *HasOneField) GetLoadingStrategy() LoadingStrategy
- func (h *HasOneField) GetOwnerKeyColumn() string
- func (h *HasOneField) GetQueryCallback() func(interface{}) interface{}
- func (h *HasOneField) GetRelatedResourceSlug() string
- func (h *HasOneField) GetRelatedTableName() string
- func (h *HasOneField) GetRelationshipName() string
- func (h *HasOneField) GetRelationshipType() string
- func (h *HasOneField) GetSearchableColumns() []string
- func (h *HasOneField) GetTypes() map[string]string
- func (h *HasOneField) HoverCard(hoverStruct interface{}) *HasOneField
- func (h *HasOneField) IsRequired() bool
- func (h *HasOneField) OwnerKey(key string) *HasOneField
- func (h *HasOneField) Query(fn func(interface{}) interface{}) *HasOneField
- func (h *HasOneField) ResolveHoverCard(resolver HoverCardResolver) *HasOneField
- func (h *HasOneField) ResolveRelationship(item interface{}) (interface{}, error)
- func (h *HasOneField) Searchable() Element
- func (h *HasOneField) ValidateRelationship(value interface{}) error
- func (h *HasOneField) WithEagerLoad() *HasOneField
- func (h *HasOneField) WithHoverCard(config HoverCardConfig) *HasOneField
- func (h *HasOneField) WithLazyLoad() *HasOneField
- type Hideable
- func (h *Hideable) GetHideCallback() func(*context.Context) bool
- func (h *Hideable) IsHidden() bool
- func (h *Hideable) SetHidden(hidden bool)
- func (h *Hideable) SetHideCallback(cb func(*context.Context) bool)
- func (h *Hideable) SetShowOnCreate(show bool)
- func (h *Hideable) SetShowOnDetail(show bool)
- func (h *Hideable) SetShowOnIndex(show bool)
- func (h *Hideable) SetShowOnUpdate(show bool)
- func (h *Hideable) ShowOnCreate() bool
- func (h *Hideable) ShowOnDetail() bool
- func (h *Hideable) ShowOnIndex() bool
- func (h *Hideable) ShowOnUpdate() bool
- type HoverCardConfig
- func (h *HoverCardConfig) Disable() *HoverCardConfig
- func (h *HoverCardConfig) SetDelays(openDelay, closeDelay int) *HoverCardConfig
- func (h *HoverCardConfig) SetResolver(resolver HoverCardResolver) *HoverCardConfig
- func (h *HoverCardConfig) SetStruct(s interface{}) *HoverCardConfig
- func (h *HoverCardConfig) SetWidth(width string) *HoverCardConfig
- type HoverCardResolver
- type LoadingStrategy
- type MorphTo
- func (m *MorphTo) Displays(displays map[string]string) *MorphTo
- func (m *MorphTo) Extract(resource interface{})
- func (m *MorphTo) GetDisplayKey() string
- func (m *MorphTo) GetHoverCard() *HoverCardConfig
- func (m *MorphTo) GetLoadingStrategy() LoadingStrategy
- func (m *MorphTo) GetQueryCallback() func(interface{}) interface{}
- func (m *MorphTo) GetRelatedResourceSlug() string
- func (m *MorphTo) GetRelationshipName() string
- func (m *MorphTo) GetRelationshipType() string
- func (m *MorphTo) GetResourceForType(morphType string) (string, error)
- func (m *MorphTo) GetSearchableColumns() []string
- func (m *MorphTo) GetTypes() map[string]string
- func (m *MorphTo) HoverCard(hoverStruct interface{}) *MorphTo
- func (m *MorphTo) IsRequired() bool
- func (m *MorphTo) Query(fn func(interface{}) interface{}) *MorphTo
- func (m *MorphTo) ResolveHoverCard(resolver HoverCardResolver) *MorphTo
- func (m *MorphTo) ResolveRelationship(item interface{}) (interface{}, error)
- func (m *MorphTo) Searchable() Element
- func (m *MorphTo) Types(types map[string]string) *MorphTo
- func (m *MorphTo) ValidateRelationship(value interface{}) error
- func (m *MorphTo) WithEagerLoad() *MorphTo
- func (m *MorphTo) WithHoverCard(config HoverCardConfig) *MorphTo
- func (m *MorphTo) WithLazyLoad() *MorphTo
- type MorphToMany
- func (m *MorphToMany) AutoOptions(displayField string) *MorphToMany
- func (m *MorphToMany) Displays(displays map[string]string) *MorphToMany
- func (m *MorphToMany) ForeignKey(key string) *MorphToMany
- func (m *MorphToMany) GetDisplayKey() string
- func (m *MorphToMany) GetLoadingStrategy() LoadingStrategy
- func (m *MorphToMany) GetQueryCallback() func(interface{}) interface{}
- func (m *MorphToMany) GetRelatedResource() string
- func (m *MorphToMany) GetRelationshipName() string
- func (m *MorphToMany) GetRelationshipType() string
- func (m *MorphToMany) GetSearchableColumns() []string
- func (m *MorphToMany) GetTypes() map[string]string
- func (m *MorphToMany) IsRequired() bool
- func (m *MorphToMany) MorphType(column string) *MorphToMany
- func (m *MorphToMany) PivotTable(tableName string) *MorphToMany
- func (m *MorphToMany) Query(fn func(interface{}) interface{}) *MorphToMany
- func (m *MorphToMany) RelatedKey(key string) *MorphToMany
- func (m *MorphToMany) ResolveRelationship(item interface{}) (interface{}, error)
- func (m *MorphToMany) Searchable() Element
- func (m *MorphToMany) Types(types map[string]string) *MorphToMany
- func (m *MorphToMany) ValidateRelationship(value interface{}) error
- func (m *MorphToMany) WithEagerLoad() *MorphToMany
- func (m *MorphToMany) WithLazyLoad() *MorphToMany
- type PanelField
- type Post
- type PostTag
- type Profile
- type RelationshipConstraints
- type RelationshipConstraintsImpl
- func (rc *RelationshipConstraintsImpl) ApplyLimit(ctx context.Context, limit int) ([]interface{}, error)
- func (rc *RelationshipConstraintsImpl) ApplyOffset(ctx context.Context, offset int) ([]interface{}, error)
- func (rc *RelationshipConstraintsImpl) ApplyWhere(ctx context.Context, column string, operator string, value interface{}) ([]interface{}, error)
- func (rc *RelationshipConstraintsImpl) ApplyWhereIn(ctx context.Context, column string, values []interface{}) ([]interface{}, error)
- func (rc *RelationshipConstraintsImpl) GetConstraints() map[string]interface{}
- func (rc *RelationshipConstraintsImpl) GetLimit() int
- func (rc *RelationshipConstraintsImpl) GetOffset() int
- type RelationshipCounting
- type RelationshipCountingImpl
- type RelationshipDisplay
- type RelationshipDisplayImpl
- type RelationshipError
- type RelationshipExistence
- type RelationshipExistenceImpl
- type RelationshipField
- type RelationshipFilter
- type RelationshipFilterImpl
- func (rf *RelationshipFilterImpl) ApplyFilter(ctx context.Context, column string, operator string, value interface{}) ([]interface{}, error)
- func (rf *RelationshipFilterImpl) ApplyMultipleFilters(ctx context.Context, filters map[string]interface{}) ([]interface{}, error)
- func (rf *RelationshipFilterImpl) GetFilters() map[string]interface{}
- func (rf *RelationshipFilterImpl) RemoveFilter(ctx context.Context) ([]interface{}, error)
- type RelationshipGormConfig
- func (r *RelationshipGormConfig) ToForeignKeyTag() string
- func (r *RelationshipGormConfig) ToGormTag() string
- func (r *RelationshipGormConfig) WithConstraintName(name string) *RelationshipGormConfig
- func (r *RelationshipGormConfig) WithForeignKey(fk string) *RelationshipGormConfig
- func (r *RelationshipGormConfig) WithOnDelete(action string) *RelationshipGormConfig
- func (r *RelationshipGormConfig) WithOnUpdate(action string) *RelationshipGormConfig
- func (r *RelationshipGormConfig) WithPivotTable(table, joinFK, joinRef string) *RelationshipGormConfig
- func (r *RelationshipGormConfig) WithPolymorphic(typeColumn, idColumn string) *RelationshipGormConfig
- func (r *RelationshipGormConfig) WithPolymorphicValue(value string) *RelationshipGormConfig
- func (r *RelationshipGormConfig) WithPreload(enabled bool) *RelationshipGormConfig
- func (r *RelationshipGormConfig) WithReferences(ref string) *RelationshipGormConfig
- type RelationshipLoader
- type RelationshipLoaderImpl
- func (rl *RelationshipLoaderImpl) EagerLoad(ctx context.Context, items []interface{}, field RelationshipField) error
- func (rl *RelationshipLoaderImpl) LazyLoad(ctx context.Context, item interface{}, field RelationshipField) (interface{}, error)
- func (rl *RelationshipLoaderImpl) LoadWithConstraints(ctx context.Context, item interface{}, field RelationshipField, ...) (interface{}, error)
- type RelationshipPagination
- type RelationshipPaginationImpl
- func (rp *RelationshipPaginationImpl) ApplyPagination(ctx context.Context, page int, perPage int) ([]interface{}, error)
- func (rp *RelationshipPaginationImpl) GetPage() int
- func (rp *RelationshipPaginationImpl) GetPageInfo() map[string]interface{}
- func (rp *RelationshipPaginationImpl) GetPerPage() int
- func (rp *RelationshipPaginationImpl) GetTotal() int64
- func (rp *RelationshipPaginationImpl) SetTotal(total int64)
- type RelationshipQuery
- type RelationshipQueryImpl
- func (rq *RelationshipQueryImpl) Count(ctx context.Context) (int64, error)
- func (rq *RelationshipQueryImpl) Exists(ctx context.Context) (bool, error)
- func (rq *RelationshipQueryImpl) First(ctx context.Context) (interface{}, error)
- func (rq *RelationshipQueryImpl) Get(ctx context.Context) ([]interface{}, error)
- func (rq *RelationshipQueryImpl) GetLimit() int
- func (rq *RelationshipQueryImpl) GetOffset() int
- func (rq *RelationshipQueryImpl) GetOrderByColumns() []map[string]interface{}
- func (rq *RelationshipQueryImpl) GetWhereConditions() []map[string]interface{}
- func (rq *RelationshipQueryImpl) Limit(limit int) RelationshipQuery
- func (rq *RelationshipQueryImpl) Offset(offset int) RelationshipQuery
- func (rq *RelationshipQueryImpl) OrderBy(column string, direction string) RelationshipQuery
- func (rq *RelationshipQueryImpl) String() string
- func (rq *RelationshipQueryImpl) Where(column string, operator string, value interface{}) RelationshipQuery
- func (rq *RelationshipQueryImpl) WhereIn(column string, values []interface{}) RelationshipQuery
- type RelationshipSearch
- type RelationshipSearchImpl
- func (rs *RelationshipSearchImpl) CaseInsensitiveSearch(ctx context.Context, term string) ([]interface{}, error)
- func (rs *RelationshipSearchImpl) GetSearchableColumns() []string
- func (rs *RelationshipSearchImpl) Search(ctx context.Context, term string) ([]interface{}, error)
- func (rs *RelationshipSearchImpl) SearchInColumns(ctx context.Context, term string, columns []string) ([]interface{}, error)
- type RelationshipSerialization
- type RelationshipSerializationImpl
- func (rs *RelationshipSerializationImpl) SerializeRelationship(item interface{}) (map[string]interface{}, error)
- func (rs *RelationshipSerializationImpl) SerializeRelationships(items []interface{}) ([]map[string]interface{}, error)
- func (rs *RelationshipSerializationImpl) ToJSON(item interface{}) (string, error)
- func (rs *RelationshipSerializationImpl) ToJSONArray(items []interface{}) (string, error)
- type RelationshipSort
- type RelationshipSortImpl
- func (rs *RelationshipSortImpl) ApplyMultipleSorts(ctx context.Context, sorts map[string]string) ([]interface{}, error)
- func (rs *RelationshipSortImpl) ApplySort(ctx context.Context, column string, direction string) ([]interface{}, error)
- func (rs *RelationshipSortImpl) GetSorts() map[string]string
- func (rs *RelationshipSortImpl) RemoveSort(ctx context.Context) ([]interface{}, error)
- type RelationshipValidator
- type RelationshipValidatorImpl
- func (rv *RelationshipValidatorImpl) ValidateBelongsTo(ctx context.Context, value interface{}, field *BelongsToField) error
- func (rv *RelationshipValidatorImpl) ValidateBelongsToMany(ctx context.Context, value interface{}, field *BelongsToManyField) error
- func (rv *RelationshipValidatorImpl) ValidateExists(ctx context.Context, value interface{}, field RelationshipField) error
- func (rv *RelationshipValidatorImpl) ValidateForeignKey(ctx context.Context, value interface{}, field RelationshipField) error
- func (rv *RelationshipValidatorImpl) ValidateHasMany(ctx context.Context, value interface{}, field *HasManyField) error
- func (rv *RelationshipValidatorImpl) ValidateHasOne(ctx context.Context, value interface{}, field *HasOneField) error
- func (rv *RelationshipValidatorImpl) ValidateMorphTo(ctx context.Context, value interface{}, field *MorphTo) error
- func (rv *RelationshipValidatorImpl) ValidateMorphType(ctx context.Context, value interface{}, field RelationshipField) error
- func (rv *RelationshipValidatorImpl) ValidatePivot(ctx context.Context, value interface{}, field RelationshipField) error
- type Resolver
- type Schema
- func Audio(name string, attribute ...string) *Schema
- func Badge(name string, attribute ...string) *Schema
- func BooleanGroup(name string, attribute ...string) *Schema
- func Code(name string, attribute ...string) *Schema
- func Collection(name string, resource string, attribute ...string) *Schema
- func Color(name string, attribute ...string) *Schema
- func Combobox(name string, attribute ...string) *Schema
- func Connect(name string, resource string, attribute ...string) *Schema
- func Date(name string, attribute ...string) *Schema
- func DateTime(name string, attribute ...string) *Schema
- func Detail(name string, resource string, attribute ...string) *Schema
- func Email(name string, attribute ...string) *Schema
- func File(name string, attribute ...string) *Schema
- func ID(name ...string) *Schema
- func Image(name string, attribute ...string) *Schema
- func KeyValue(name string, attribute ...string) *Schema
- func Link(name string, resource string, attribute ...string) *Schema
- func Matrix(name string, attribute ...string) *Schema
- func Money(name string, attribute ...string) *Schema
- func NewField(name string, attribute ...string) *Schema
- func Number(name string, attribute ...string) *Schema
- func Password(name string, attribute ...string) *Schema
- func PolyCollection(name string, resource string, attribute ...string) *Schema
- func PolyConnect(name string, resource string, attribute ...string) *Schema
- func PolyDetail(name string, resource string, attribute ...string) *Schema
- func PolyLink(name string, attribute ...string) *Schema
- func RichText(name string, attribute ...string) *Schema
- func Select(name string, attribute ...string) *Schema
- func Stack(children []core.Element) *Schema
- func Switch(name string, attribute ...string) *Schema
- func Tel(name string, attribute ...string) *Schema
- func Text(name string, attribute ...string) *Schema
- func Textarea(name string, attribute ...string) *Schema
- func Video(name string, attribute ...string) *Schema
- func (s *Schema) Accept(mimeTypes ...string) core.Element
- func (s *Schema) AddValidationRule(rule interface{}) core.Element
- func (s *Schema) AllowCustomCurrency(allow bool) *Schema
- func (s *Schema) AsPivot() core.Element
- func (s *Schema) AutoOptions(displayField string) Element
- func (s *Schema) CanSee(fn VisibilityFunc) Element
- func (s *Schema) CreationRules(rules ...interface{}) core.Element
- func (s *Schema) Currencies(currencies ...Currency) *Schema
- func (s *Schema) Currency(currency string) *Schema
- func (s *Schema) CurrencyEnum(currency Currency) *Schema
- func (s *Schema) CustomCurrencies(currencies ...string) *Schema
- func (s *Schema) Default(value interface{}) Element
- func (s *Schema) DependsOn(fields ...string) core.Element
- func (s *Schema) Disabled() Element
- func (s *Schema) Display(fn interface{}) core.Element
- func (s *Schema) DisplayAs(format string) core.Element
- func (s *Schema) DisplayUsingLabels() core.Element
- func (s *Schema) Email() core.Element
- func (s *Schema) Exists(table, column string) core.Element
- func (s *Schema) Extract(resource interface{})
- func (s *Schema) Fields(fields ...core.Element) core.Element
- func (s *Schema) Filterable() Element
- func (s *Schema) GetAcceptedMimeTypes() []string
- func (s *Schema) GetAutoCompleteURL() string
- func (s *Schema) GetAutoOptionsConfig() core.AutoOptionsConfig
- func (s *Schema) GetBadgeVariant() string
- func (s *Schema) GetContext() ElementContext
- func (s *Schema) GetCreationValidationRules() []interface{}
- func (s *Schema) GetCustomValidators() []interface{}
- func (s *Schema) GetDependencies() []string
- func (s *Schema) GetDependencyCallback(context string) DependencyCallbackFunc
- func (s *Schema) GetDependencyRules() map[string]interface{}
- func (s *Schema) GetDisplayCallback() func(value interface{}, item interface{}) interface{}
- func (s *Schema) GetDisplayedAs() string
- func (s *Schema) GetEditorLanguage() string
- func (s *Schema) GetEditorTheme() string
- func (s *Schema) GetEditorType() string
- func (s *Schema) GetGormConfig() *GormConfig
- func (s *Schema) GetKey() string
- func (s *Schema) GetMaxFileSize() int64
- func (s *Schema) GetMaxRepeats() int
- func (s *Schema) GetMetadata() map[string]interface{}
- func (s *Schema) GetMinCharsForSuggestions() int
- func (s *Schema) GetMinRepeats() int
- func (s *Schema) GetModifyCallback() func(value interface{}, c *fiber.Ctx) interface{}
- func (s *Schema) GetName() string
- func (s *Schema) GetPivotResourceName() string
- func (s *Schema) GetRepeaterFields() []Element
- func (s *Schema) GetResolveCallback() func(value interface{}, item interface{}, c *fiber.Ctx) interface{}
- func (s *Schema) GetResolveHandle() string
- func (s *Schema) GetStatusColors() map[string]string
- func (s *Schema) GetStorageCallback() StorageCallbackFunc
- func (s *Schema) GetStorageDisk() string
- func (s *Schema) GetStoragePath() string
- func (s *Schema) GetSuggestions(query string) []interface{}
- func (s *Schema) GetSuggestionsCallback() func(string) []interface{}
- func (s *Schema) GetType() core.ElementType
- func (s *Schema) GetUpdateValidationRules() []interface{}
- func (s *Schema) GetUploadCallback() func(interface{}, interface{}) error
- func (s *Schema) GetValidationRules() []interface{}
- func (s *Schema) GetView() string
- func (s *Schema) Gorm(config *GormConfig) Element
- func (s *Schema) GormAutoIncrement() Element
- func (s *Schema) GormComment(comment string) Element
- func (s *Schema) GormDefault(value interface{}) Element
- func (s *Schema) GormForeignKey(fk, references string) Element
- func (s *Schema) GormFullTextIndex(name ...string) Element
- func (s *Schema) GormIndex(name ...string) Element
- func (s *Schema) GormOnDelete(action string) Element
- func (s *Schema) GormOnUpdate(action string) Element
- func (s *Schema) GormPrimaryKey() Element
- func (s *Schema) GormSize(size int) Element
- func (s *Schema) GormSnowflake() Element
- func (s *Schema) GormSoftDelete() Element
- func (s *Schema) GormType(sqlType string) Element
- func (s *Schema) GormULID() Element
- func (s *Schema) GormUUID() Element
- func (s *Schema) GormUniqueIndex(name ...string) Element
- func (s *Schema) HasGormConfig() bool
- func (s *Schema) HelpText(helpText string) Element
- func (s *Schema) HideNumberControls() Element
- func (s *Schema) HideOnApi() Element
- func (s *Schema) HideOnCreate() Element
- func (s *Schema) HideOnDetail() Element
- func (s *Schema) HideOnGrid() Element
- func (s *Schema) HideOnList() Element
- func (s *Schema) HideOnUpdate() Element
- func (s *Schema) Immutable() Element
- func (s *Schema) IsConditionallyVisible(item interface{}) bool
- func (s *Schema) IsHidden(ctx VisibilityContext) bool
- func (s *Schema) IsPivot() bool
- func (s *Schema) IsRepeaterField() bool
- func (s *Schema) IsSearchable() bool
- func (s *Schema) IsVisible(ctx *core.ResourceContext) bool
- func (s *Schema) IsVisibleInContext(ctx VisibilityContext) bool
- func (s *Schema) JsonSerialize() map[string]interface{}
- func (s *Schema) Label(label string) Element
- func (s *Schema) MarkRemoveEXIFData() core.Element
- func (s *Schema) Mask(mask string) *Schema
- func (s *Schema) MaskChar(maskChar string) *Schema
- func (s *Schema) Max(max interface{}) core.Element
- func (s *Schema) MaxLength(length int) core.Element
- func (s *Schema) MaxRepeats(max int) core.Element
- func (s *Schema) MaxSize(bytes int64) core.Element
- func (s *Schema) Min(min interface{}) core.Element
- func (s *Schema) MinCharsForSuggestions(min int) core.Element
- func (s *Schema) MinLength(length int) core.Element
- func (s *Schema) MinRepeats(min int) core.Element
- func (s *Schema) Modify(fn func(value interface{}, c *fiber.Ctx) interface{}) Element
- func (s *Schema) Nullable() Element
- func (s *Schema) OnDependencyChange(fn DependencyCallbackFunc) core.Element
- func (s *Schema) OnDependencyChangeCreating(fn DependencyCallbackFunc) core.Element
- func (s *Schema) OnDependencyChangeUpdating(fn DependencyCallbackFunc) core.Element
- func (s *Schema) OnDetail() Element
- func (s *Schema) OnForm() Element
- func (s *Schema) OnList() Element
- func (s *Schema) OnlyOnCreate() Element
- func (s *Schema) OnlyOnDetail() Element
- func (s *Schema) OnlyOnForm() Element
- func (s *Schema) OnlyOnList() Element
- func (s *Schema) OnlyOnUpdate() Element
- func (s *Schema) Options(options interface{}) Element
- func (s *Schema) Pattern(pattern string) core.Element
- func (s *Schema) Placeholder(placeholder string) Element
- func (s *Schema) ReadOnly() Element
- func (s *Schema) RemoveEXIFData(ctx interface{}, file interface{}) error
- func (s *Schema) Required() Element
- func (s *Schema) Resolve(fn func(value interface{}, item interface{}, c *fiber.Ctx) interface{}) Element
- func (s *Schema) ResolveDependencies(context interface{}) bool
- func (s *Schema) ResolveForDisplay(item interface{}) (interface{}, error)
- func (s *Schema) ResolveHandle(handle string) core.Element
- func (s *Schema) Rows(rows int) Element
- func (s *Schema) Rules(rules ...interface{}) core.Element
- func (s *Schema) Searchable() Element
- func (s *Schema) SetContext(context ElementContext) Element
- func (s *Schema) SetContextForI18n(c *fiber.Ctx)
- func (s *Schema) SetDependencies(deps []string) Element
- func (s *Schema) SetKey(key string) Element
- func (s *Schema) SetName(name string) Element
- func (s *Schema) SetTextAlign(align string) Element
- func (s *Schema) ShouldDisplayUsingLabels() bool
- func (s *Schema) ShouldRemoveEXIFData() bool
- func (s *Schema) ShowCurrency(show bool) *Schema
- func (s *Schema) ShowNumberControls(show bool) Element
- func (s *Schema) ShowOnGrid() Element
- func (s *Schema) ShowOnlyGrid() Element
- func (s *Schema) Sortable() Element
- func (s *Schema) Span(span int) Element
- func (s *Schema) Stacked() Element
- func (s *Schema) Store(disk, path string) core.Element
- func (s *Schema) StoreAs(fn StorageCallbackFunc) Element
- func (s *Schema) Tooltip(text string) Element
- func (s *Schema) URL() core.Element
- func (s *Schema) Unique(table, column string) core.Element
- func (s *Schema) UpdateRules(rules ...interface{}) core.Element
- func (s *Schema) ValidateAttachment(filename string, size int64) error
- func (s *Schema) ValidateRepeats(count int) error
- func (s *Schema) ValidateValue(value interface{}) error
- func (s *Schema) When(field string, operator string, value interface{}) core.Element
- func (s *Schema) WithAutoComplete(url string) core.Element
- func (s *Schema) WithBadgeVariant(variant string) core.Element
- func (s *Schema) WithEditor(editorType string) core.Element
- func (s *Schema) WithLanguage(language string) core.Element
- func (s *Schema) WithPivotResource(resourceName string) core.Element
- func (s *Schema) WithProps(key string, value interface{}) Element
- func (s *Schema) WithStatusColors(colors map[string]string) core.Element
- func (s *Schema) WithSuggestions(fn func(string) []interface{}) core.Element
- func (s *Schema) WithTheme(theme string) core.Element
- func (s *Schema) WithUpload(fn func(interface{}, interface{}) error) core.Element
- type Searchable
- type Sortable
- func (s *Sortable) GetSortCallback() func(*gorm.DB, string) *gorm.DB
- func (s *Sortable) GetSortDirection() string
- func (s *Sortable) IsSortable() bool
- func (s *Sortable) SetSortCallback(cb func(*gorm.DB, string) *gorm.DB)
- func (s *Sortable) SetSortDirection(direction string)
- func (s *Sortable) SetSortable(sortable bool)
- type StorageCallbackFunc
- type Tab
- type TabsField
- func (t *TabsField) AddTab(value, label string, fields ...core.Element) *TabsField
- func (t *TabsField) GetFields() []core.Element
- func (t *TabsField) WithDefaultTab(value string) *TabsField
- func (t *TabsField) WithSide(side string) *TabsField
- func (t *TabsField) WithVariant(variant string) *TabsField
- type Tag
- type Taggable
- type TestDB
- type User
- type Validatable
- type ValidationResult
- type ValidationRule
- func EmailRule() ValidationRule
- func Exists(table, column string) ValidationRule
- func Max(max interface{}) ValidationRule
- func MaxLength(length int) ValidationRule
- func MergeValidationRules(base, extra []ValidationRule) []ValidationRule
- func Min(min interface{}) ValidationRule
- func MinLength(length int) ValidationRule
- func Pattern(pattern string) ValidationRule
- func Required() ValidationRule
- func URL() ValidationRule
- func Unique(table, column string) ValidationRule
- type ValidatorFunc
- type VisibilityContext
- type VisibilityFunc
Constants ¶
This section is empty.
Variables ¶
var DefaultCurrencies = []Currency{ CurrencyUSD, CurrencyEUR, CurrencyTRY, CurrencyGBP, }
DefaultCurrencies, money field için önerilen başlangıç para birimi listesidir.
Functions ¶
func ApplyConditionalValidation ¶
func ApplyConditionalValidation(validator ConditionalValidator, value interface{}, context interface{}) error
ApplyConditionalValidation applies a validator only if condition is met
func ApplyCustomValidator ¶
ApplyCustomValidator applies a global custom validator
func ApplyValidationRule ¶
func ApplyValidationRule(rule ValidationRule, value interface{}) error
ApplyValidationRule applies a validation rule to a value
func GetTestDataDir ¶
func GetTestDataDir() string
GetTestDataDir, test verileri için geçici dizin yolunu döndürür.
Bu fonksiyon, test sırasında geçici dosyaların saklanması gereken dizin yolunu sağlar. İşletim sisteminin standart geçici dizinini kullanır.
Dönüş Değeri ¶
İşletim sisteminin geçici dizin yolunu string olarak döndürür. - Unix/Linux/macOS: Genellikle `/tmp` - Windows: Genellikle `C:\Users\<username>\AppData\Local\Temp`
Kullanım Senaryoları ¶
- Test sırasında geçici dosya oluşturma - Test verilerini diske yazma - Dosya yükleme testleri - Önbellek testleri
Önemli Notlar ¶
- **Geçici Dizin**: Döndürülen dizin işletim sistemi tarafından yönetilir - **Temizlik**: Test sonunda oluşturulan dosyaları manuel olarak temizlemek gerekebilir - **İzinler**: Geçici dizine yazma izni genellikle mevcuttur - **Çakışma**: Benzersiz dosya adları kullanarak çakışmaları önleyin
Örnek Kullanım ¶
```go
func TestFileUpload(t *testing.T) {
testDir := GetTestDataDir()
testFile := filepath.Join(testDir, "test_upload.txt")
// Test dosyası oluştur
err := os.WriteFile(testFile, []byte("test data"), 0644)
if err != nil {
t.Fatal(err)
}
defer os.Remove(testFile) // Temizlik
// Test kodunuz...
}
// Benzersiz dosya adı ile kullanım
func TestWithUniqueFile(t *testing.T) {
testDir := GetTestDataDir()
testFile := filepath.Join(testDir, fmt.Sprintf("test_%d.txt", time.Now().UnixNano()))
// Test kodunuz...
}
```
func RegisterCustomValidator ¶
func RegisterCustomValidator(name string, validator ValidatorFunc)
RegisterCustomValidator registers a global custom validator
func ValidateEmail ¶
func ValidateEmail(value interface{}) error
ValidateEmail, e-posta formatını doğrular.
Bu fonksiyon, RFC 5322 standardına uygun e-posta adresi formatını kontrol eder. Boş string geçerli sayılır (zorunluluk için Required() kullanın).
Parametreler ¶
- **value**: Doğrulanacak değer (string olmalı)
Kullanım Örneği ¶
err := fields.ValidateEmail("[email protected]") // nil
err := fields.ValidateEmail("invalid-email") // error: "invalid email format"
err := fields.ValidateEmail("") // nil (boş geçerli)
Döndürür:
- nil: E-posta formatı geçerli veya boş
- error: E-posta formatı geçersiz veya tip uyumsuz
func ValidateMax ¶
func ValidateMax(value interface{}, max interface{}) error
ValidateMax validates maximum value
func ValidateMaxLength ¶
ValidateMaxLength validates maximum string length
func ValidateMin ¶
func ValidateMin(value interface{}, min interface{}) error
ValidateMin validates minimum value
func ValidateMinLength ¶
ValidateMinLength validates minimum string length
func ValidatePattern ¶
ValidatePattern validates regex pattern matching
func ValidateRequired ¶
func ValidateRequired(value interface{}) error
ValidateRequired, bir değerin boş olmadığını doğrular.
Bu fonksiyon, değerin nil, boş string, boş slice olmadığını kontrol eder. Farklı veri tipleri için farklı boşluk kontrolleri yapar.
Parametreler ¶
- **value**: Doğrulanacak değer (interface{})
Desteklenen Tipler ¶
- **nil**: Hata döndürür - **string**: Boşluk karakterleri temizlendikten sonra boş string kontrolü - **[]interface{}**: Boş slice kontrolü - **[]string**: Boş string slice kontrolü
Kullanım Örneği ¶
err := fields.ValidateRequired("test") // nil
err := fields.ValidateRequired("") // error: "value is required"
err := fields.ValidateRequired(nil) // error: "value is required"
Döndürür:
- nil: Değer geçerli
- error: Değer boş
Types ¶
type BelongsToField ¶
type BelongsToField struct {
Schema
RelatedResourceSlug string
RelatedResource interface{} // resource.Resource interface (interface{} to avoid circular import)
DisplayKey string
SearchableColumns []string
QueryCallback func(query interface{}) interface{}
LoadingStrategy LoadingStrategy
GormRelationConfig *RelationshipGormConfig
// contains filtered or unexported fields
}
BelongsToField, ters one-to-one ilişkiyi temsil eder (örn. Post -> Author).
BelongsTo ilişkisi, bir kaydın başka bir kayda ait olduğunu belirtir. Bu, veritabanında foreign key ile temsil edilir.
Kullanım Senaryoları ¶
- **Post -> Author**: Bir yazı bir yazara aittir - **Comment -> User**: Bir yorum bir kullanıcıya aittir - **Order -> Customer**: Bir sipariş bir müşteriye aittir
Özellikler ¶
- **Tip Güvenliği**: Resource instance veya string slug kullanılabilir - **Otomatik Seçenekler**: AutoOptions ile veritabanından otomatik seçenek yükleme - **Arama Desteği**: İlişkili kayıtlarda arama yapabilme - **Eager/Lazy Loading**: Yükleme stratejisi seçimi - **GORM Yapılandırması**: Foreign key ve references özelleştirme - **Hover Card**: Index ve detail sayfalarında hover card desteği
Kullanım Örneği ¶
// String slug ile
field := fields.BelongsTo("Author", "author_id", "authors").
DisplayUsing("name").
WithSearchableColumns("name", "email").
AutoOptions("name").
WithEagerLoad()
// Resource instance ile (tip güvenli)
field := fields.BelongsTo("Author", "author_id", blog.NewAuthorResource()).
DisplayUsing("name").
WithSearchableColumns("name", "email").
AutoOptions("name").
WithEagerLoad()
// Hover card ile
field := fields.BelongsTo("Author", "author_id", "authors").
DisplayUsing("name").
WithHoverCard(fields.NewHoverCardConfig().
WithAvatar("avatar", "").
WithGrid([]fields.HoverCardGridField{
{Key: "email", Label: "Email", Type: "email", Icon: "mail"},
{Key: "role", Label: "Rol", Type: "badge"},
}, "2-column"))
Daha fazla bilgi için docs/Relationships.md dosyasına bakın.
func BelongsTo ¶
func BelongsTo(name, key string, relatedResource interface{}) *BelongsToField
BelongsTo, yeni bir BelongsTo ilişki alanı oluşturur.
Bu fonksiyon, hem string slug hem de resource instance kabul eder. Resource instance kullanımı tip güvenliği sağlar ve refactoring'i kolaylaştırır.
Parametreler ¶
- **name**: Alanın görünen adı (örn. "Author", "Yazar") - **key**: Foreign key sütun adı (örn. "author_id") - **relatedResource**: İlgili resource (string slug veya resource instance)
String Slug Kullanımı ¶
field := fields.BelongsTo("Author", "author_id", "authors")
**Avantajlar:** - Basit ve hızlı - Circular import sorunu yok
**Dezavantajlar:** - Tip güvenliği yok - Refactoring zor - IDE desteği sınırlı
Resource Instance Kullanımı (Önerilen) ¶
field := fields.BelongsTo("Author", "author_id", blog.NewAuthorResource())
**Avantajlar:** - ✅ Tip güvenliği (derleme zamanı kontrolü) - ✅ Refactoring desteği (resource adı değişirse otomatik güncellenir) - ✅ IDE desteği (autocomplete, go-to-definition) - ✅ Tablo adı otomatik alınır (resource.Slug())
**Dezavantajlar:** - Circular import'a dikkat edilmeli
Varsayılan Değerler ¶
- **DisplayKey**: "name" (görüntüleme için kullanılacak alan) - **SearchableColumns**: ["name"] (aranabilir sütunlar) - **LoadingStrategy**: EAGER_LOADING (N+1 sorgu problemini önler) - **Foreign Key**: key parametresi (örn. "author_id") - **References**: "id" (ilgili tablonun primary key'i)
Döndürür:
- Yapılandırılmış BelongsToField pointer'ı
Daha fazla bilgi için docs/Relationships.md ve .docs/RESOURCE_BASED_RELATIONSHIPS.md dosyalarına bakın.
func (*BelongsToField) AutoOptions ¶
func (b *BelongsToField) AutoOptions(displayField string) *BelongsToField
AutoOptions, ilgili tablodan otomatik seçenek oluşturmayı etkinleştirir.
Bu metod, backend'in veritabanından otomatik olarak tüm kayıtları çekip form elemanları (Combobox/Select) için seçenekler oluşturmasını sağlar. Manuel olarak Options callback'i tanımlamaya gerek kalmaz.
Parametreler ¶
- **displayField**: Seçenek etiketi için kullanılacak sütun adı (örn. "name", "title", "email")
Kullanım Örneği ¶
field := fields.BelongsTo("Author", "author_id", "authors").
AutoOptions("name")
// Backend otomatik olarak authors tablosundan tüm kayıtları çeker
// ve "name" sütununu etiket olarak kullanır
Önemli Notlar ¶
- AutoOptions kullanıldığında, backend otomatik olarak ilgili tablodan tüm kayıtları çeker - Büyük tablolar için performans sorunu olabilir, bu durumda Query() ile filtreleme yapılmalıdır - displayField, ilgili tabloda mevcut bir sütun olmalıdır
Döndürür:
- BelongsToField pointer'ı (method chaining için)
Daha fazla bilgi için docs/Relationships.md dosyasına bakın.
func (*BelongsToField) DisplayUsing ¶
func (b *BelongsToField) DisplayUsing(key string) *BelongsToField
DisplayUsing, ilişkili resource'u göstermek için kullanılacak key'i ayarlar.
Bu metod, ilişkili kaydın hangi field'ının görüntüleneceğini belirler. Varsayılan olarak "name" field'ı kullanılır.
Parametreler ¶
- **key**: Görüntüleme için kullanılacak field adı (örn. "name", "title", "email", "username")
Kullanım Örneği ¶
field := fields.BelongsTo("Author", "author_id", "authors").
DisplayUsing("email")
// Author'un email'i görüntülenir
Yaygın Kullanım Senaryoları ¶
- **name**: Genel amaçlı görüntüleme (varsayılan) - **title**: Başlık alanları için - **email**: E-posta adresi görüntüleme - **username**: Kullanıcı adı görüntüleme - **full_name**: Tam ad görüntüleme
Döndürür:
- BelongsToField pointer'ı (method chaining için)
func (*BelongsToField) Extract ¶
func (b *BelongsToField) Extract(record any)
Extract, BelongsTo ilişkisini minimal formatta serialize eder.
Bu metod, ilişkili kaydı {"id": ..., "title": ...} formatında döndürür. Record title pattern'ini takip eder.
Çalışma Mantığı ¶
1. Schema.Extract ile foreign key değerini alır 2. İlişki eager loaded ise ve RelatedResource varsa:
- İlişkili kaydın ID'sini alır
- RelatedResource.RecordTitle ile başlığı alır
- {"id": foreignKey, "title": recordTitle} formatında döndürür
3. İlişki yüklenmemişse veya nil ise null döndürür
Önemli Notlar ¶
- İlişki eager loaded olmalı (WithEagerLoad veya Preload kullanılmalı) - RelatedResource nil ise sadece foreign key değeri döner - DisplayUsing callback'i varsa öncelik verilir
Kullanım Örneği ¶
// Post -> Author ilişkisi
post := &Post{
ID: 1,
AuthorID: 5,
Author: &User{ID: 5, Name: "John Doe"},
}
field.Extract(&post)
// field.Data = {"id": 5, "title": "John Doe"}
// İlişki yüklenmemiş
post := &Post{ID: 1, AuthorID: 5, Author: nil}
field.Extract(&post)
// field.Data = nil
Parametreler:
- record: Kayıt instance'ı (pointer olmalı)
func (*BelongsToField) GetDisplayKey ¶
func (b *BelongsToField) GetDisplayKey() string
GetDisplayKey returns the display key
func (*BelongsToField) GetForeignKey ¶
func (b *BelongsToField) GetForeignKey() string
GetForeignKey, foreign key sütun adını döndürür.
Bu metod, BelongsTo ilişkisinde kullanılan foreign key sütununun adını döndürür. GormRelationConfig'den foreign key bilgisini alır.
Dönüş Değeri ¶
- Foreign key sütun adı (örn. "author_id", "user_id") - GormRelationConfig nil ise boş string döner
Kullanım Örneği ¶
field := fields.BelongsTo("Author", "author_id", "authors")
foreignKey := field.GetForeignKey() // "author_id"
Döndürür:
- Foreign key sütun adı
func (*BelongsToField) GetHoverCard ¶
func (b *BelongsToField) GetHoverCard() *HoverCardConfig
GetHoverCard, hover card konfigürasyonunu döndürür.
Bu metod, hover card konfigürasyonunu alır.
Döndürür:
- HoverCardConfig pointer'ı (nil olabilir)
func (*BelongsToField) GetLoadingStrategy ¶
func (b *BelongsToField) GetLoadingStrategy() LoadingStrategy
GetLoadingStrategy returns the loading strategy
func (*BelongsToField) GetOwnerKeyColumn ¶
func (b *BelongsToField) GetOwnerKeyColumn() string
GetOwnerKeyColumn, owner key sütun adını döndürür.
Bu metod, BelongsTo ilişkisinde kullanılan owner key (references) sütununun adını döndürür. Owner key, ilişkili tablodaki referans sütunudur (genellikle primary key).
Dönüş Değeri ¶
- Owner key sütun adı (örn. "id", "uuid") - GormRelationConfig nil ise varsayılan olarak "id" döner
Kullanım Örneği ¶
field := fields.BelongsTo("Author", "author_id", "authors")
ownerKey := field.GetOwnerKeyColumn() // "id"
Döndürür:
- Owner key sütun adı
func (*BelongsToField) GetQueryCallback ¶
func (b *BelongsToField) GetQueryCallback() func(interface{}) interface{}
GetQueryCallback returns the query callback
func (*BelongsToField) GetRelatedResource ¶
func (b *BelongsToField) GetRelatedResource() string
GetRelatedResource returns the related resource slug
func (*BelongsToField) GetRelatedResourceSlug ¶
func (b *BelongsToField) GetRelatedResourceSlug() string
GetRelatedResourceSlug, ilişkili resource'un slug'ını döndürür.
Bu metod, BelongsTo ilişkisinde kullanılan ilişkili resource'un slug'ını döndürür.
Dönüş Değeri ¶
- İlişkili resource slug'ı (örn. "authors", "users", "categories")
Kullanım Örneği ¶
field := fields.BelongsTo("Author", "author_id", "authors")
slug := field.GetRelatedResourceSlug() // "authors"
Döndürür:
- İlişkili resource slug'ı
func (*BelongsToField) GetRelatedTableName ¶
func (b *BelongsToField) GetRelatedTableName() string
GetRelatedTableName, ilişkili tablo adını döndürür.
Bu metod, BelongsTo ilişkisinde kullanılan ilişkili tablonun adını döndürür. Raw SQL sorguları için kullanılır.
Dönüş Değeri ¶
- İlişkili tablo adı (örn. "authors", "users", "categories")
Kullanım Örneği ¶
field := fields.BelongsTo("Author", "author_id", "authors")
tableName := field.GetRelatedTableName() // "authors"
Döndürür:
- İlişkili tablo adı
func (*BelongsToField) GetRelationshipName ¶
func (b *BelongsToField) GetRelationshipName() string
GetRelationshipName returns the relationship name
func (*BelongsToField) GetRelationshipType ¶
func (b *BelongsToField) GetRelationshipType() string
GetRelationshipType returns the relationship type
func (*BelongsToField) GetSearchableColumns ¶
func (b *BelongsToField) GetSearchableColumns() []string
GetSearchableColumns returns the searchable columns
func (*BelongsToField) GetTypes ¶
func (b *BelongsToField) GetTypes() map[string]string
GetTypes returns the type mappings (not used for BelongsTo)
func (*BelongsToField) HoverCard ¶
func (b *BelongsToField) HoverCard(hoverStruct interface{}) *BelongsToField
HoverCard, hover card struct'ını ayarlar ve hover card'ı etkinleştirir.
Bu metod, hover card için kullanılacak struct'ı belirler ve hover card özelliğini aktif eder.
Parametreler ¶
- **hoverStruct**: Hover card verisi için kullanılacak struct (örn. &AuthorHoverCard{})
Kullanım Örneği ¶
type AuthorHoverCard struct {
Avatar string `json:"avatar"`
Name string `json:"name"`
Email string `json:"email"`
Phone string `json:"phone"`
}
field := fields.BelongsTo("Author", "author_id", "authors").
DisplayUsing("name").
HoverCard(&AuthorHoverCard{})
Döndürür:
- BelongsToField pointer'ı (method chaining için)
func (*BelongsToField) IsRequired ¶
func (b *BelongsToField) IsRequired() bool
IsRequired returns whether the field is required
func (*BelongsToField) Query ¶
func (b *BelongsToField) Query(fn func(interface{}) interface{}) *BelongsToField
Query sets the query callback for customizing relationship query
func (*BelongsToField) ResolveHoverCard ¶
func (b *BelongsToField) ResolveHoverCard(resolver HoverCardResolver) *BelongsToField
ResolveHoverCard, hover card verilerini çözmek için callback fonksiyonunu ayarlar.
Bu metod, hover card açıldığında çağrılacak resolver fonksiyonunu belirler. Resolver, ilişkili kaydın hover card verilerini döndürür.
Parametreler ¶
- **resolver**: Hover card resolver callback fonksiyonu
Kullanım Örneği ¶
field := fields.BelongsTo("Author", "author_id", "authors").
DisplayUsing("name").
HoverCard(&AuthorHoverCard{}).
ResolveHoverCard(func(ctx context.Context, record interface{}, relatedID interface{}, field fields.Field) (interface{}, error) {
// İlişkili kaydı veritabanından al
author := &Author{}
if err := db.First(author, relatedID).Error; err != nil {
return nil, err
}
// Hover card verisini döndür
return &AuthorHoverCard{
Avatar: author.Avatar,
Name: author.Name,
Email: author.Email,
Phone: author.Phone,
}, nil
})
API Endpoint ¶
Frontend, hover card açıldığında şu endpoint'e istek atar:
GET /api/resource/{resource}/resolver/{field_name}?id={related_id}
POST /api/resource/{resource}/resolver/{field_name} (body: {id: related_id})
Döndürür:
- BelongsToField pointer'ı (method chaining için)
func (*BelongsToField) ResolveRelationship ¶
func (b *BelongsToField) ResolveRelationship(item interface{}) (interface{}, error)
ResolveRelationship resolves the relationship value using reflection
func (*BelongsToField) Searchable ¶
func (b *BelongsToField) Searchable() Element
Searchable, alanı aranabilir olarak işaretler (Element interface'ini implement eder).
Bu metod, alanın global arama işlemlerine dahil edilmesini sağlar. Global arama yapıldığında, bu alan da arama sonuçlarına dahil edilir.
Kullanım Örneği ¶
field := fields.BelongsTo("Author", "author_id", "authors").
Searchable()
// Bu alan global arama işlemlerine dahil edilir
Önemli Notlar ¶
- Global arama, tüm aranabilir alanlarda arama yapar - WithSearchableColumns() ile birlikte kullanılmalıdır - Performans için dikkatli kullanılmalıdır
Döndürür:
- Element interface'i (method chaining için)
func (*BelongsToField) ValidateRelationship ¶
func (b *BelongsToField) ValidateRelationship(value interface{}) error
ValidateRelationship validates the relationship
func (*BelongsToField) WithEagerLoad ¶
func (b *BelongsToField) WithEagerLoad() *BelongsToField
WithEagerLoad sets the loading strategy to eager loading
func (*BelongsToField) WithHoverCard ¶
func (b *BelongsToField) WithHoverCard(config HoverCardConfig) *BelongsToField
WithHoverCard, hover card konfigürasyonunu ayarlar.
Bu metod, index ve detail sayfalarında ilişkili kaydın hover card ile nasıl görüntüleneceğini belirler.
Parametreler ¶
- **config**: Hover card konfigürasyonu
Kullanım Örneği (Deprecated - Yeni API kullanın) ¶
field := fields.BelongsTo("Author", "author_id", "authors").
WithHoverCard(*fields.NewHoverCardConfig())
Yeni API (Önerilen) ¶
field := fields.BelongsTo("Author", "author_id", "authors").
HoverCard(&AuthorHoverCard{}).
ResolveHoverCard(func(ctx context.Context, record interface{}, relatedID interface{}, field fields.Field) (interface{}, error) {
// Custom logic
return &AuthorHoverCard{...}, nil
})
Döndürür:
- BelongsToField pointer'ı (method chaining için)
func (*BelongsToField) WithLazyLoad ¶
func (b *BelongsToField) WithLazyLoad() *BelongsToField
WithLazyLoad sets the loading strategy to lazy loading
func (*BelongsToField) WithSearchableColumns ¶
func (b *BelongsToField) WithSearchableColumns(columns ...string) *BelongsToField
WithSearchableColumns, BelongsTo için aranabilir sütunları ayarlar.
Bu metod, ilişkili kayıtlarda arama yapılabilecek sütunları belirler. Bu sütunlar, combobox'ta arama yaparken kullanılır.
Parametreler ¶
- **columns**: Aranabilir sütun adlarının listesi (örn. "name", "email", "username")
Kullanım Örneği ¶
field := fields.BelongsTo("Author", "author_id", "authors").
WithSearchableColumns("name", "email", "username")
// Kullanıcı combobox'ta arama yaptığında name, email ve username sütunlarında arama yapılır
Önemli Notlar ¶
- Aranabilir sütunlar, ilgili tabloda mevcut olmalıdır - Çok fazla sütun eklemek performans sorunlarına neden olabilir - Genellikle 2-4 sütun yeterlidir
Döndürür:
- BelongsToField pointer'ı (method chaining için)
type BelongsToManyField ¶
type BelongsToManyField struct {
Schema
RelatedResourceSlug string
RelatedResource interface{} // resource.Resource interface (interface{} to avoid circular import)
PivotTableName string
ForeignKeyColumn string
RelatedKeyColumn string
QueryCallback func(query interface{}) interface{}
LoadingStrategy LoadingStrategy
GormRelationConfig *RelationshipGormConfig
}
BelongsToManyField, many-to-many ilişkiyi temsil eder (örn. User -> Roles).
BelongsToMany ilişkisi, bir kaydın birden fazla ilişkili kayda sahip olduğunu ve ilişkili kayıtların da birden fazla kayda sahip olabileceğini belirtir. Bu, veritabanında pivot (ara) tablo ile temsil edilir.
Kullanım Senaryoları ¶
- **User -> Roles**: Bir kullanıcının birden fazla rolü vardır, bir rol birden fazla kullanıcıya atanabilir - **Post -> Tags**: Bir yazının birden fazla etiketi vardır, bir etiket birden fazla yazıda kullanılabilir - **Student -> Courses**: Bir öğrenci birden fazla kursa kayıtlıdır, bir kursta birden fazla öğrenci vardır
Özellikler ¶
- **Tip Güvenliği**: Resource instance veya string slug kullanılabilir - **Pivot Tablo**: Ara tablo adı otomatik oluşturulur veya özelleştirilebilir - **Foreign Key Özelleştirme**: Ana tablodaki foreign key sütunu özelleştirilebilir - **Related Key Özelleştirme**: İlişkili tablodaki foreign key sütunu özelleştirilebilir - **Eager/Lazy Loading**: Yükleme stratejisi seçimi - **GORM Yapılandırması**: Pivot tablo ve key'ler özelleştirilebilir
Kullanım Örneği ¶
// String slug ile
field := fields.BelongsToMany("Roles", "roles", "roles").
PivotTable("user_roles").
ForeignKey("user_id").
RelatedKey("role_id").
WithEagerLoad()
// Resource instance ile (tip güvenli)
field := fields.BelongsToMany("Roles", "roles", user.NewRoleResource()).
PivotTable("user_roles").
ForeignKey("user_id").
RelatedKey("role_id").
WithEagerLoad()
Pivot Tablo Yapısı ¶
Pivot tablo genellikle şu yapıya sahiptir:
CREATE TABLE user_roles (
user_id INT,
role_id INT,
PRIMARY KEY (user_id, role_id)
);
Daha fazla bilgi için docs/Relationships.md dosyasına bakın.
func BelongsToMany ¶
func BelongsToMany(name, key string, relatedResource interface{}) *BelongsToManyField
BelongsToMany, yeni bir BelongsToMany ilişki alanı oluşturur.
Bu fonksiyon, hem string slug hem de resource instance kabul eder. Resource instance kullanımı tip güvenliği sağlar ve refactoring'i kolaylaştırır.
Parametreler ¶
- **name**: Alanın görünen adı (örn. "Roles", "Roller") - **key**: İlişki key'i (örn. "roles") - **relatedResource**: İlgili resource (string slug veya resource instance)
String Slug Kullanımı ¶
field := fields.BelongsToMany("Tags", "tags", "tags")
Resource Instance Kullanımı (Önerilen) ¶
field := fields.BelongsToMany("Tags", "tags", blog.NewTagResource())
**Avantajlar:** - ✅ Tip güvenliği (derleme zamanı kontrolü) - ✅ Refactoring desteği - ✅ IDE desteği (autocomplete, go-to-definition)
Varsayılan Değerler ¶
- **PivotTableName**: Otomatik oluşturulur (örn. "post_tag", "user_role") - **ForeignKeyColumn**: "user_id" (ana tablonun foreign key'i) - **RelatedKeyColumn**: slug + "_id" (örn. "role_id", "tag_id") - **LoadingStrategy**: EAGER_LOADING (N+1 sorgu problemini önler)
Döndürür:
- Yapılandırılmış BelongsToManyField pointer'ı
func (*BelongsToManyField) AutoOptions ¶
func (b *BelongsToManyField) AutoOptions(displayField string) *BelongsToManyField
AutoOptions enables automatic options generation from the related table. displayField is the column name to use for the option label.
func (*BelongsToManyField) Count ¶
func (b *BelongsToManyField) Count() int64
Count returns the count of related resources
func (*BelongsToManyField) Extract ¶
func (b *BelongsToManyField) Extract(resource interface{})
Extract, BelongsToMany ilişkisini minimal formatta serialize eder.
Bu metod, ilişkili kayıtları [{"id": ..., "title": ...}, ...] formatında döndürür. Record title pattern'ini takip eder.
Çalışma Mantığı ¶
1. Schema.Extract ile ilişki verilerini alır 2. Data nil ise boş array döndürür 3. RelatedResource varsa her kayıt için:
- ID field'ını alır
- RelatedResource.RecordTitle ile başlığı alır
- {"id": ..., "title": ...} formatında ekler
4. İlişki yüklenmemişse boş array döndürür
Önemli Notlar ¶
- İlişki eager loaded olmalı (WithEagerLoad veya Preload kullanılmalı) - RelatedResource nil ise mevcut veri döner - HasMany ile aynı mantıkta çalışır
Kullanım Örneği ¶
// User -> Roles ilişkisi
user := &User{
ID: 1,
Roles: []Role{
{ID: 1, Name: "Admin"},
{ID: 2, Name: "Editor"},
},
}
field.Extract(&user)
// field.Data = [{"id": 1, "title": "Admin"}, {"id": 2, "title": "Editor"}]
// İlişki yüklenmemiş
user := &User{ID: 1, Roles: nil}
field.Extract(&user)
// field.Data = []
Parametreler:
- record: Kayıt instance'ı (pointer olmalı)
func (*BelongsToManyField) ForeignKey ¶
func (b *BelongsToManyField) ForeignKey(key string) *BelongsToManyField
ForeignKey sets the foreign key in pivot table
func (*BelongsToManyField) GetDisplayKey ¶
func (b *BelongsToManyField) GetDisplayKey() string
GetDisplayKey returns the display key (not used for BelongsToMany)
func (*BelongsToManyField) GetLoadingStrategy ¶
func (b *BelongsToManyField) GetLoadingStrategy() LoadingStrategy
GetLoadingStrategy returns the loading strategy
func (*BelongsToManyField) GetQueryCallback ¶
func (b *BelongsToManyField) GetQueryCallback() func(interface{}) interface{}
GetQueryCallback returns the query callback
func (*BelongsToManyField) GetRelatedResourceSlug ¶
func (b *BelongsToManyField) GetRelatedResourceSlug() string
GetRelatedResource returns the related resource slug
func (*BelongsToManyField) GetRelationshipName ¶
func (b *BelongsToManyField) GetRelationshipName() string
GetRelationshipName returns the relationship name
func (*BelongsToManyField) GetRelationshipType ¶
func (b *BelongsToManyField) GetRelationshipType() string
GetRelationshipType returns the relationship type
func (*BelongsToManyField) GetSearchableColumns ¶
func (b *BelongsToManyField) GetSearchableColumns() []string
GetSearchableColumns returns the searchable columns (not used for BelongsToMany)
func (*BelongsToManyField) GetTypes ¶
func (b *BelongsToManyField) GetTypes() map[string]string
GetTypes returns the type mappings (not used for BelongsToMany)
func (*BelongsToManyField) IsRequired ¶
func (b *BelongsToManyField) IsRequired() bool
IsRequired returns whether the field is required
func (*BelongsToManyField) PivotTable ¶
func (b *BelongsToManyField) PivotTable(table string) *BelongsToManyField
PivotTable sets the pivot table name
func (*BelongsToManyField) Query ¶
func (b *BelongsToManyField) Query(fn func(interface{}) interface{}) *BelongsToManyField
Query sets the query callback for customizing relationship query
func (*BelongsToManyField) RelatedKey ¶
func (b *BelongsToManyField) RelatedKey(key string) *BelongsToManyField
RelatedKey sets the related key in pivot table
func (*BelongsToManyField) ResolveRelationship ¶
func (b *BelongsToManyField) ResolveRelationship(item interface{}) (interface{}, error)
ResolveRelationship resolves the relationship by loading through pivot table
func (*BelongsToManyField) Searchable ¶
func (b *BelongsToManyField) Searchable() Element
Searchable marks the element as searchable (implements Element interface)
func (*BelongsToManyField) ValidateRelationship ¶
func (b *BelongsToManyField) ValidateRelationship(value interface{}) error
ValidateRelationship validates the relationship
func (*BelongsToManyField) WithEagerLoad ¶
func (b *BelongsToManyField) WithEagerLoad() *BelongsToManyField
WithEagerLoad sets the loading strategy to eager loading
func (*BelongsToManyField) WithLazyLoad ¶
func (b *BelongsToManyField) WithLazyLoad() *BelongsToManyField
WithLazyLoad sets the loading strategy to lazy loading
type Comment ¶
type Comment struct {
// ID, yorumun benzersiz kimliğidir (primary key).
ID int `json:"id"`
// PostID, yorumun yapıldığı gönderinin ID'sidir (foreign key).
PostID int `json:"post_id"`
// UserID, yorumu yapan kullanıcının ID'sidir (foreign key).
UserID int `json:"user_id"`
// Content, yorumun içeriğidir.
Content string `json:"content"`
// Post, yorumun yapıldığı gönderidir (BelongsTo ilişkisi).
// Bu alan opsiyoneldir ve eager loading ile doldurulur.
Post *Post `json:"post,omitempty"`
// Author, yorumu yapan kullanıcıdır (BelongsTo ilişkisi).
// Bu alan opsiyoneldir ve eager loading ile doldurulur.
Author *User `json:"author,omitempty"`
}
Comment, bir gönderi yorumunu temsil eden model yapısıdır.
Bu model, kullanıcıların gönderilere yaptığı yorumları tutar ve birden fazla BelongsTo ilişkisinin test edilmesinde kullanılır.
İlişkiler ¶
- **BelongsTo**: Post (her yorum bir gönderiye aittir) - **BelongsTo**: User (her yorum bir kullanıcıya aittir)
JSON Serileştirme ¶
Post ve Author alanları opsiyoneldir ve `omitempty` ile işaretlenmiştir. İlişkiler yüklenmemişse JSON'da görünmez.
Örnek Kullanım ¶
```go var comment Comment err := db.QueryRow(`
SELECT c.id, c.post_id, c.user_id, c.content,
p.id, p.title,
u.id, u.name
FROM comments c
LEFT JOIN posts p ON c.post_id = p.id
LEFT JOIN users u ON c.user_id = u.id
WHERE c.id = ?
`, 1).Scan(&comment.ID, &comment.PostID, &comment.UserID, &comment.Content,
&comment.Post.ID, &comment.Post.Title, &comment.Author.ID, &comment.Author.Name)
```
type ConditionalValidator ¶
type ConditionalValidator struct {
Condition func(context interface{}) bool
Validator ValidatorFunc
}
ConditionalValidator represents a validator that applies conditionally
type Currency ¶
type Currency string
Currency, money field'larında kullanılacak ISO 4217 currency kodunu temsil eder.
type CustomValidatorRegistry ¶
type CustomValidatorRegistry struct {
// contains filtered or unexported fields
}
CustomValidatorRegistry stores custom validators
func NewCustomValidatorRegistry ¶
func NewCustomValidatorRegistry() *CustomValidatorRegistry
NewCustomValidatorRegistry creates a new custom validator registry
func (*CustomValidatorRegistry) Apply ¶
func (r *CustomValidatorRegistry) Apply(name string, value interface{}, context interface{}) error
Apply applies a custom validator
func (*CustomValidatorRegistry) Get ¶
func (r *CustomValidatorRegistry) Get(name string) (ValidatorFunc, bool)
Get retrieves a custom validator
func (*CustomValidatorRegistry) Register ¶
func (r *CustomValidatorRegistry) Register(name string, validator ValidatorFunc)
Register registers a custom validator
type DependencyCallbackFunc ¶
type DependencyCallbackFunc func( field *Schema, formData map[string]interface{}, ctx *fiber.Ctx, ) *FieldUpdate
DependencyCallbackFunc, form alanları arasındaki bağımlılık ilişkilerini yönetmek için kullanılan callback fonksiyon tipidir.
Genel Bakış ¶
Bu fonksiyon tipi, bir alanın değeri değiştiğinde diğer alanların davranışını dinamik olarak değiştirmek için kullanılır. Örneğin, bir dropdown'da seçilen değere göre başka bir alanı göstermek/gizlemek, zorunlu hale getirmek veya seçeneklerini değiştirmek gibi işlemler yapılabilir.
Kullanım Senaryoları ¶
- **Koşullu Alan Görünürlüğü**: Bir alanın değerine göre diğer alanları göster/gizle - **Dinamik Validasyon**: Bir alanın değerine göre diğer alanların validasyon kurallarını değiştir - **Cascade Seçenekler**: Bir dropdown'ın seçimine göre diğer dropdown'ların seçeneklerini filtrele - **Koşullu Zorunluluk**: Belirli koşullarda alanları zorunlu veya opsiyonel yap - **Dinamik Yardım Metinleri**: Bağlama göre yardım metinlerini güncelle
Parametreler ¶
- `field`: Bağımlılık kuralının uygulanacağı hedef alan şeması - `formData`: Form verilerini içeren map (tüm alanların güncel değerleri) - `ctx`: Fiber context nesnesi (HTTP request/response bilgilerine erişim için)
Dönüş Değeri ¶
`*FieldUpdate`: Alana uygulanacak güncellemeleri içeren nesne. nil döndürülürse hiçbir güncelleme yapılmaz.
Kullanım Örneği ¶
```go // Ülke seçimine göre şehir alanını göster/gizle
countryField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
country := formData["country"]
if country == "TR" {
return NewFieldUpdate().Show().MakeRequired()
}
return NewFieldUpdate().Hide().MakeOptional()
})
// Ürün tipine göre fiyat alanının validasyonunu değiştir
productTypeField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
productType := formData["product_type"]
if productType == "premium" {
return NewFieldUpdate().
SetHelpText("Premium ürünler için minimum 1000 TL").
AddRule(ValidationRule{Type: "min", Value: 1000})
}
return NewFieldUpdate().SetHelpText("Standart fiyatlandırma")
})
```
Önemli Notlar ¶
- Callback fonksiyonu her form değişikliğinde çağrılabilir, bu nedenle performans açısından hafif olmalıdır - Sonsuz döngülerden kaçınmak için dikkatli olunmalıdır (A alanı B'yi tetikler, B alanı A'yı tetikler) - formData map'i güvenli bir şekilde kontrol edilmeli, nil veya eksik değerler için kontrol yapılmalıdır - Context üzerinden veritabanı sorguları yapılabilir ancak performans etkileri göz önünde bulundurulmalıdır
Avantajlar ¶
- Dinamik ve esnek form davranışı sağlar - Kullanıcı deneyimini iyileştirir (gereksiz alanları gizler) - Karmaşık iş kurallarını kolayca uygular - Sunucu tarafında kontrol sağlar (güvenlik)
Dezavantajlar ¶
- Yanlış kullanımda performans sorunlarına yol açabilir - Karmaşık bağımlılık zincirleri debug edilmesi zor olabilir - Sonsuz döngü riski vardır
type DependencyResolver ¶
type DependencyResolver struct {
// contains filtered or unexported fields
}
DependencyResolver ¶
Alan bağımlılıklarını çözen ve yöneten ana yapı.
## Amaç
Form alanları arasındaki bağımlılık ilişkilerini yönetir ve bir alan değiştiğinde ona bağımlı diğer alanların otomatik olarak güncellenmesini sağlar.
## Yapı Alanları
- `fields`: Tüm form alanlarının listesi - `context`: Bağımlılık çözme bağlamı (örn: "form", "filter", "detail")
## Çalışma Prensibi
1. Alanlar arası bağımlılık grafiği oluşturulur 2. Değişen alanlar tespit edilir 3. BFS algoritması ile etkilenen tüm alanlar bulunur 4. Her etkilenen alan için ilgili callback fonksiyonları çalıştırılır 5. Güncellenmiş alan bilgileri döndürülür
## Avantajlar
- **Performans**: Graf yapısı sayesinde O(V+E) karmaşıklığında çalışır - **Esneklik**: Context bazlı farklı bağımlılık kuralları tanımlanabilir - **Güvenlik**: Döngüsel bağımlılık tespiti ile sonsuz döngüler önlenir - **Modülerlik**: Her alan kendi bağımlılık callback'ini tanımlayabilir
## Dezavantajlar
- Çok karmaşık bağımlılık ağlarında performans düşebilir - Callback fonksiyonlarının doğru yazılması gerekir
## Önemli Notlar
⚠️ **Uyarı**: Döngüsel bağımlılıklar sonsuz döngüye neden olabilir. Mutlaka `DetectCircularDependencies()` ile kontrol edin.
💡 **İpucu**: Context parametresi ile aynı alanlar farklı bağlamlarda farklı davranabilir (örn: form vs filter).
func NewDependencyResolver ¶
func NewDependencyResolver(fields []*Schema, context string) *DependencyResolver
NewDependencyResolver ¶
Yeni bir bağımlılık çözücü oluşturur.
## Parametreler
- `fields`: Bağımlılık çözümlemesi yapılacak alan listesi - `context`: Bağımlılık çözme bağlamı (örn: "form", "filter", "detail")
## Dönüş Değeri
Yapılandırılmış `*DependencyResolver` örneği döner.
## Kullanım Örneği
```go
fields := []*Schema{
{Key: "country", DependsOnFields: []string{}},
{Key: "city", DependsOnFields: []string{"country"}},
{Key: "district", DependsOnFields: []string{"city"}},
}
resolver := NewDependencyResolver(fields, "form") ```
## Önemli Notlar
- Context parametresi, aynı alanların farklı bağlamlarda farklı davranmasını sağlar - Oluşturulduktan sonra `DetectCircularDependencies()` ile kontrol yapılması önerilir
func (*DependencyResolver) DetectCircularDependencies ¶
func (r *DependencyResolver) DetectCircularDependencies() error
DetectCircularDependencies ¶
Alan bağımlılıkları arasında döngüsel (circular) bağımlılık olup olmadığını tespit eder.
## Amaç
Bağımlılık grafiğinde döngü (cycle) olup olmadığını kontrol eder. Döngüsel bağımlılıklar sonsuz döngülere ve stack overflow hatalarına neden olabileceği için, sistem başlatılırken veya alan tanımları değiştiğinde bu kontrolün yapılması kritik önem taşır.
## Dönüş Değeri
- `nil`: Döngüsel bağımlılık yok, sistem güvenli - `error`: Döngüsel bağımlılık tespit edildi, hata mesajında ilgili alan belirtilir
## Döngüsel Bağımlılık Nedir?
Döngüsel bağımlılık, alanların birbirine doğrudan veya dolaylı olarak bağımlı olduğu ve bir döngü oluşturduğu durumdur.
### Örnekler
**Doğrudan Döngü:** ``` Alan A -> Alan B -> Alan A ```
**Dolaylı Döngü:** ``` Alan A -> Alan B -> Alan C -> Alan A ```
**Karmaşık Döngü:** ``` Alan A -> Alan B -> Alan C
↓ ↓ Alan D -> Alan E -> Alan A
```
## Kullanım Örneği
```go // Alan tanımları
fields := []*Schema{
{Key: "country", DependsOnFields: []string{"city"}}, // Hatalı!
{Key: "city", DependsOnFields: []string{"country"}}, // Döngü!
}
resolver := NewDependencyResolver(fields, "form")
// Döngüsel bağımlılık kontrolü
if err := resolver.DetectCircularDependencies(); err != nil {
log.Fatal(err) // "circular dependency detected involving field: country"
}
```
## Doğru Kullanım
```go // Doğru alan tanımları (tek yönlü bağımlılık)
fields := []*Schema{
{Key: "country", DependsOnFields: []string{}},
{Key: "city", DependsOnFields: []string{"country"}},
{Key: "district", DependsOnFields: []string{"city"}},
}
resolver := NewDependencyResolver(fields, "form")
// Kontrol başarılı
if err := resolver.DetectCircularDependencies(); err != nil {
log.Fatal(err)
}
// Hata yok, sistem güvenli ```
## Algoritma: DFS (Depth-First Search)
1. Her alan için DFS başlat (henüz ziyaret edilmemişse) 2. Alanı ziyaret edildi olarak işaretle 3. Alanı recursion stack'e ekle 4. Alanın bağımlılarını kontrol et:
- Bağımlı henüz ziyaret edilmemişse, recursive DFS çağrısı yap
- Bağımlı recursion stack'te varsa, döngü tespit edildi
5. Alanı recursion stack'ten çıkar
## Performans
- **Zaman Karmaşıklığı**: O(V + E)
- V: Toplam alan sayısı
- E: Toplam bağımlılık sayısı
- **Alan Karmaşıklığı**: O(V)
- visited ve recStack map'leri için
## Ne Zaman Çağrılmalı?
1. **Sistem Başlatma**: Uygulama başlarken tüm alanlar için kontrol 2. **Alan Tanımı Değişikliği**: Yeni alan eklendiğinde veya bağımlılık değiştiğinde 3. **Geliştirme Aşaması**: Unit testlerde otomatik kontrol 4. **Deployment Öncesi**: CI/CD pipeline'da validasyon
## Önemli Notlar
**UYARI**: Bu fonksiyon mutlaka çağrılmalıdır. Döngüsel bağımlılıklar runtime'da sonsuz döngüye ve sistem çökmesine neden olabilir.
**NOT**: Hata mesajı sadece döngüye dahil olan alanlardan birini gösterir. Tüm döngüyü görmek için ek analiz gerekebilir.
**İPUCU**: Geliştirme ortamında panic kullanarak erken tespit yapılabilir: ```go
if err := resolver.DetectCircularDependencies(); err != nil {
panic(err) // Geliştirme ortamında hemen fark edilir
}
```
## Test Örneği
```go
func TestCircularDependency(t *testing.T) {
fields := []*Schema{
{Key: "a", DependsOnFields: []string{"b"}},
{Key: "b", DependsOnFields: []string{"c"}},
{Key: "c", DependsOnFields: []string{"a"}}, // Döngü!
}
resolver := NewDependencyResolver(fields, "test")
err := resolver.DetectCircularDependencies()
assert.Error(t, err)
assert.Contains(t, err.Error(), "circular dependency")
}
```
func (*DependencyResolver) ResolveDependencies ¶
func (r *DependencyResolver) ResolveDependencies( formData map[string]interface{}, changedFields []string, ctx *fiber.Ctx, ) (map[string]*FieldUpdate, error)
ResolveDependencies ¶
Değişen alanlara bağlı tüm alanları tespit eder ve güncelleme bilgilerini döner.
## Amaç
Form verilerinde değişiklik olan alanları tespit edip, bu alanlara bağımlı olan diğer tüm alanları bulur ve her biri için ilgili callback fonksiyonlarını çalıştırarak güncellenmiş alan bilgilerini döner.
## Parametreler
- `formData`: Güncel form verilerini içeren map (alan adı -> değer) - `changedFields`: Değişiklik yapılan alan anahtarlarının listesi - `ctx`: Fiber context nesnesi (HTTP request/response bilgileri için)
## Dönüş Değerleri
- `map[string]*FieldUpdate`: Alan anahtarı -> güncelleme bilgisi map'i - `error`: Hata durumunda hata mesajı
## Çalışma Algoritması
1. **Graf Oluşturma**: Tüm alanlar arası bağımlılık grafiği oluşturulur 2. **BFS Traversal**: Değişen alanlardan başlayarak BFS ile etkilenen alanlar bulunur 3. **Callback Çalıştırma**: Her etkilenen alan için context'e uygun callback çalıştırılır 4. **Sonuç Toplama**: Tüm güncellemeler bir map'te toplanır
## Kullanım Örneği
```go // Form verisi
formData := map[string]interface{}{
"country": "TR",
"city": "Istanbul",
}
// Değişen alanlar changedFields := []string{"country"}
// Bağımlılıkları çöz updates, err := resolver.ResolveDependencies(formData, changedFields, ctx)
if err != nil {
return err
}
// Güncellemeleri uygula
for fieldKey, update := range updates {
fmt.Printf("Alan %s güncellendi: %+v\n", fieldKey, update)
}
```
## Performans
- **Zaman Karmaşıklığı**: O(V + E) - V: alan sayısı, E: bağımlılık sayısı - **Alan Karmaşıklığı**: O(V) - Visited ve affected map'leri için
## Önemli Notlar
⚠️ **Uyarı**: Callback fonksiyonları içinde hata oluşursa, bu alan için güncelleme döndürülmez ancak diğer alanlar işlenmeye devam eder.
💡 **İpucu**: Context parametresi sayesinde aynı alan farklı bağlamlarda (form, filter, detail) farklı callback'ler kullanabilir.
📌 **Not**: Döngüsel bağımlılıklar varsa sonsuz döngüye girmez, visited map'i sayesinde her alan sadece bir kez işlenir.
type DialogContentType ¶
type DialogContentType string
DialogContentType, dialog içeriğinin tipini belirler (form veya wizard)
const ( // DialogContentForm - Basit form içeriği DialogContentForm DialogContentType = "form" // DialogContentWizard - Multi-step wizard içeriği DialogContentWizard DialogContentType = "wizard" )
type DialogField ¶
type DialogField struct {
*Schema
// contains filtered or unexported fields
}
DialogField, modal/dialog içinde form veya wizard gösteren bir field tipidir
Kullanım Senaryosu: - Kullanıcıdan modal içinde veri toplamak için - Multi-step wizard formları için - Sayfa geçişlerinde kullanıcıyı bilgilendirmek için
Özellikler: - Varsayılan açık veya buton ile tetiklenebilir - Basit form veya multi-step wizard mode - Özelleştirilebilir dialog boyutu - OnComplete ve OnSkip callback'leri
Örnek Kullanım (Basit Form):
Dialog("Profil Tamamla", "profile_completion").
DefaultOpen(true).
DialogTitle("Profilinizi Tamamlayın").
Content([]core.Element{
Text("Telefon", "phone").Required(),
Text("Adres", "address").Required(),
}).
OnComplete(func(ctx *fiber.Ctx, data map[string]any) error {
// Veriyi kaydet
return nil
})
Örnek Kullanım (Wizard):
Dialog("Onboarding", "onboarding_wizard").
TriggerButton("Başlangıç Rehberini Başlat").
DialogTitle("Hoş Geldiniz!").
Wizard([]DialogStep{
{
Index: 0,
Title: "Kişisel Bilgiler",
Fields: []core.Element{Text("Ad", "name").Required()},
CanSkip: false,
},
{
Index: 1,
Title: "Tercihler",
Fields: []core.Element{Switch("Bildirimler", "notifications")},
CanSkip: true,
},
})
func Dialog ¶
func Dialog(name string, key ...string) *DialogField
Dialog, yeni bir DialogField oluşturur
Parametreler:
- name: Field'ın görüntü adı
- key: Veritabanı anahtarı (opsiyonel)
Dönüş Değeri:
- *DialogField: Yapılandırılmış dialog field pointer'ı
Örnek Kullanım:
field := Dialog("Profil Tamamla", "profile_completion")
func (*DialogField) Content ¶
func (f *DialogField) Content(fields []core.Element) *DialogField
Content, basit form içeriğini ayarlar
Parametreler:
- fields: Form field'ları
Dönüş Değeri:
- *DialogField: Method chaining için
Örnek Kullanım:
Dialog("Profil", "profile").Content([]core.Element{
Text("Ad", "name").Required(),
Email("Email", "email").Required(),
})
func (*DialogField) DefaultOpen ¶
func (f *DialogField) DefaultOpen(open bool) *DialogField
DefaultOpen, dialog'un varsayılan olarak açık olup olmayacağını ayarlar
Parametreler:
- open: true ise dialog sayfa yüklendiğinde otomatik açılır
Dönüş Değeri:
- *DialogField: Method chaining için
Örnek Kullanım:
Dialog("Profil", "profile").DefaultOpen(true)
func (*DialogField) DialogDesc ¶
func (f *DialogField) DialogDesc(desc string) *DialogField
DialogDesc, dialog açıklamasını ayarlar
Parametreler:
- desc: Dialog açıklaması
Dönüş Değeri:
- *DialogField: Method chaining için
Örnek Kullanım:
Dialog("Profil", "profile").DialogDesc("Lütfen bilgilerinizi güncelleyin")
func (*DialogField) DialogSize ¶
func (f *DialogField) DialogSize(size string) *DialogField
DialogSize, dialog boyutunu ayarlar
Parametreler:
- size: Dialog boyutu ("sm", "md", "lg", "xl", "full")
Dönüş Değeri:
- *DialogField: Method chaining için
Örnek Kullanım:
Dialog("Profil", "profile").DialogSize("lg")
func (*DialogField) DialogTitle ¶
func (f *DialogField) DialogTitle(title string) *DialogField
DialogTitle, dialog başlığını ayarlar
Parametreler:
- title: Dialog başlığı
Dönüş Değeri:
- *DialogField: Method chaining için
Örnek Kullanım:
Dialog("Profil", "profile").DialogTitle("Profilinizi Düzenleyin")
func (*DialogField) Extract ¶
func (f *DialogField) Extract(resource interface{})
Extract, DialogField için veri çıkarır (core.Element interface implementasyonu)
func (*DialogField) GetContext ¶
func (f *DialogField) GetContext() ElementContext
GetContext, DialogField'ın context'ini döndürür (core.Element interface implementasyonu)
func (*DialogField) GetKey ¶
func (f *DialogField) GetKey() string
GetKey, DialogField'ın key'ini döndürür (core.Element interface implementasyonu)
func (*DialogField) GetView ¶
func (f *DialogField) GetView() string
GetView, DialogField'ın view tipini döndürür (core.Element interface implementasyonu)
func (*DialogField) JsonSerialize ¶
func (f *DialogField) JsonSerialize() map[string]any
JsonSerialize, DialogField'ı JSON uyumlu bir map'e serileştirir
Bu metod, DialogField'ın tüm özelliklerini frontend'e göndermek için JSON formatına dönüştürür.
Dönüş Değeri:
- map[string]any: JSON uyumlu map
Örnek Kullanım:
field := Dialog("Profil", "profile").DefaultOpen(true)
json := field.JsonSerialize()
// json["view"] == "dialog"
// json["defaultOpen"] == true
func (*DialogField) OnComplete ¶
func (f *DialogField) OnComplete(fn func(ctx *fiber.Ctx, data map[string]any) error) *DialogField
OnComplete, dialog tamamlandığında çağrılacak callback'i ayarlar
Parametreler:
- fn: Callback fonksiyonu
Dönüş Değeri:
- *DialogField: Method chaining için
Örnek Kullanım:
Dialog("Profil", "profile").OnComplete(func(ctx *fiber.Ctx, data map[string]any) error {
// Veriyi kaydet
return nil
})
func (*DialogField) OnSkip ¶
func (f *DialogField) OnSkip(fn func(ctx *fiber.Ctx) error) *DialogField
OnSkip, dialog atlandığında çağrılacak callback'i ayarlar (wizard için)
Parametreler:
- fn: Callback fonksiyonu
Dönüş Değeri:
- *DialogField: Method chaining için
Örnek Kullanım:
Dialog("Onboarding", "onboarding").OnSkip(func(ctx *fiber.Ctx) error {
// Atlandı işaretini kaydet
return nil
})
func (*DialogField) TriggerButton ¶
func (f *DialogField) TriggerButton(text string) *DialogField
TriggerButton, dialog'u açacak butonun metnini ayarlar
Parametreler:
- text: Buton metni
Dönüş Değeri:
- *DialogField: Method chaining için
Örnek Kullanım:
Dialog("Profil", "profile").TriggerButton("Profili Düzenle")
func (*DialogField) TriggerIcon ¶
func (f *DialogField) TriggerIcon(icon string) *DialogField
TriggerIcon, dialog butonunun ikonunu ayarlar
Parametreler:
- icon: İkon (emoji veya icon class)
Dönüş Değeri:
- *DialogField: Method chaining için
Örnek Kullanım:
Dialog("Profil", "profile").TriggerIcon("✏️")
func (*DialogField) Wizard ¶
func (f *DialogField) Wizard(steps []DialogStep) *DialogField
Wizard, multi-step wizard içeriğini ayarlar
Parametreler:
- steps: Wizard adımları
Dönüş Değeri:
- *DialogField: Method chaining için
Örnek Kullanım:
Dialog("Onboarding", "onboarding").Wizard([]DialogStep{
{
Index: 0,
Title: "Adım 1",
Fields: []core.Element{Text("Ad", "name")},
CanSkip: false,
},
})
type DialogStep ¶
type DialogStep struct {
Index int `json:"index"` // Adım sırası (0'dan başlar)
Title string `json:"title"` // Adım başlığı
Description string `json:"description"` // Adım açıklaması
Fields []core.Element `json:"fields"` // Adımdaki field'lar
CanSkip bool `json:"can_skip"` // Adım atlanabilir mi?
}
DialogStep, wizard mode için bir adımı temsil eder
Kullanım Senaryosu: - Multi-step form wizard'ları için - Her adım kendi field'larına sahip - Adımlar atlanabilir veya zorunlu olabilir
Örnek Kullanım:
step := DialogStep{
Index: 0,
Title: "Kişisel Bilgiler",
Description: "Lütfen kişisel bilgilerinizi girin",
Fields: []core.Element{
Text("Ad", "name").Required(),
Email("Email", "email").Required(),
},
CanSkip: false,
}
type Displayable ¶
type Displayable struct {
// contains filtered or unexported fields
}
Displayable, alanların görüntüleme formatını özelleştirmesini sağlayan bir mixin'dir.
Alan değerlerinin UI'da nasıl render edileceğini kontrol eden görüntüleme callback'leri ve format string'leri için yapılandırma sağlar.
Kullanım ¶
type TextField struct {
fields.Base
fields.Displayable
}
field := &TextField{}
field.SetDisplayFormat("uppercase")
field.SetDisplayCallback(func(ctx *context.Context, value any) string {
return strings.ToUpper(value.(string))
})
Daha fazla örnek için docs/Fields.md dosyasına bakın.
func (*Displayable) GetDisplayCallback ¶
func (d *Displayable) GetDisplayCallback() func(*context.Context, any) string
GetDisplayCallback, görüntüleme callback fonksiyonunu döndürür. Hiçbir callback ayarlanmamışsa nil döndürür.
Döndürür:
- Görüntüleme callback fonksiyonu veya ayarlanmamışsa nil
func (*Displayable) GetDisplayFormat ¶
func (d *Displayable) GetDisplayFormat() string
GetDisplayFormat, görüntüleme format string'ini döndürür. Hiçbir format ayarlanmamışsa boş string döndürür.
Döndürür:
- Görüntüleme format tanımlayıcısı
func (*Displayable) SetDisplayCallback ¶
func (d *Displayable) SetDisplayCallback(cb func(*context.Context, any) string)
SetDisplayCallback, özel bir görüntüleme callback fonksiyonu ayarlar.
Callback, context ve alan değerini alır, ve görüntüleme için değerin formatlanmış string temsilini döndürmelidir.
Parametreler:
- cb: Alan değerini görüntüleme için formatlayan fonksiyon
Örnek:
field.SetDisplayCallback(func(ctx *context.Context, value any) string {
timestamp, ok := value.(time.Time)
if !ok {
return ""
}
return timestamp.Format("2006-01-02 15:04:05")
})
func (*Displayable) SetDisplayFormat ¶
func (d *Displayable) SetDisplayFormat(format string)
SetDisplayFormat, görüntüleme format string'ini ayarlar.
Format string'i, frontend'e değerin nasıl görüntüleneceği hakkında bir ipucudur (örn. "uppercase", "lowercase", "currency", "date").
Parametreler:
- format: Görüntüleme format tanımlayıcısı
Örnek:
field.SetDisplayFormat("currency")
type Element ¶
Element, admin panel'deki bir UI elemanını temsil eder.
Bu tip, core.Element'in bir alias'ıdır ve tüm field türleri (Text, Number, BelongsTo, vb.) bu interface'i implement eder.
Daha fazla bilgi için pkg/core/element.go dosyasına bakın.
type ElementContext ¶
type ElementContext = core.ElementContext
ElementContext, bir elemanın hangi bağlamda görüntüleneceğini belirtir.
Bu tip, core.ElementContext'in bir alias'ıdır ve elemanların form, liste veya detay sayfalarında görünürlüğünü kontrol eder.
Daha fazla bilgi için pkg/core/element_context.go dosyasına bakın.
const ( CONTEXT_FORM ElementContext = core.CONTEXT_FORM CONTEXT_DETAIL ElementContext = core.CONTEXT_DETAIL CONTEXT_LIST ElementContext = core.CONTEXT_LIST CONTEXT_GRID ElementContext = core.CONTEXT_GRID SHOW_ON_FORM ElementContext = core.SHOW_ON_FORM SHOW_ON_DETAIL ElementContext = core.SHOW_ON_DETAIL SHOW_ON_LIST ElementContext = core.SHOW_ON_LIST SHOW_ON_GRID ElementContext = core.SHOW_ON_GRID HIDE_ON_LIST ElementContext = core.HIDE_ON_LIST HIDE_ON_GRID ElementContext = core.HIDE_ON_GRID HIDE_ON_DETAIL ElementContext = core.HIDE_ON_DETAIL HIDE_ON_CREATE ElementContext = core.HIDE_ON_CREATE HIDE_ON_UPDATE ElementContext = core.HIDE_ON_UPDATE HIDE_ON_API ElementContext = core.HIDE_ON_API ONLY_ON_LIST ElementContext = core.ONLY_ON_LIST ONLY_ON_GRID ElementContext = core.ONLY_ON_GRID ONLY_ON_DETAIL ElementContext = core.ONLY_ON_DETAIL ONLY_ON_CREATE ElementContext = core.ONLY_ON_CREATE ONLY_ON_UPDATE ElementContext = core.ONLY_ON_UPDATE ONLY_ON_FORM ElementContext = core.ONLY_ON_FORM )
type ElementType ¶
type ElementType = core.ElementType
ElementType, bir elemanın tipini belirtir.
Bu tip, core.ElementType'ın bir alias'ıdır ve her field türünün (Text, Number, BelongsTo, vb.) hangi UI bileşenini kullanacağını belirler.
Daha fazla bilgi için pkg/core/element_type.go dosyasına bakın.
const ( TYPE_TEXT ElementType = core.TYPE_TEXT TYPE_TEXTAREA ElementType = core.TYPE_TEXTAREA TYPE_RICHTEXT ElementType = core.TYPE_RICHTEXT TYPE_PASSWORD ElementType = core.TYPE_PASSWORD TYPE_NUMBER ElementType = core.TYPE_NUMBER TYPE_MONEY ElementType = core.TYPE_MONEY TYPE_TEL ElementType = core.TYPE_TEL TYPE_EMAIL ElementType = core.TYPE_EMAIL TYPE_AUDIO ElementType = core.TYPE_AUDIO TYPE_VIDEO ElementType = core.TYPE_VIDEO TYPE_DATE ElementType = core.TYPE_DATE TYPE_DATETIME ElementType = core.TYPE_DATETIME TYPE_FILE ElementType = core.TYPE_FILE TYPE_KEY_VALUE ElementType = core.TYPE_KEY_VALUE TYPE_LINK ElementType = core.TYPE_LINK TYPE_COLLECTION ElementType = core.TYPE_COLLECTION TYPE_DETAIL ElementType = core.TYPE_DETAIL TYPE_CONNECT ElementType = core.TYPE_CONNECT TYPE_POLY_LINK ElementType = core.TYPE_POLY_LINK TYPE_POLY_DETAIL ElementType = core.TYPE_POLY_DETAIL TYPE_POLY_COLLECTION ElementType = core.TYPE_POLY_COLLECTION TYPE_POLY_CONNECT ElementType = core.TYPE_POLY_CONNECT TYPE_BOOLEAN ElementType = core.TYPE_BOOLEAN TYPE_SELECT ElementType = core.TYPE_SELECT TYPE_PANEL ElementType = core.TYPE_PANEL TYPE_TABS ElementType = core.TYPE_TABS TYPE_STACK ElementType = core.TYPE_STACK TYPE_RELATIONSHIP ElementType = core.TYPE_RELATIONSHIP TYPE_BADGE ElementType = core.TYPE_BADGE TYPE_CODE ElementType = core.TYPE_CODE TYPE_COLOR ElementType = core.TYPE_COLOR TYPE_BOOLEAN_GROUP ElementType = core.TYPE_BOOLEAN_GROUP )
type FieldUpdate ¶
type FieldUpdate struct {
Visible *bool `json:"visible,omitempty"`
ReadOnly *bool `json:"readonly,omitempty"`
Required *bool `json:"required,omitempty"`
Disabled *bool `json:"disabled,omitempty"`
HelpText *string `json:"helpText,omitempty"`
Placeholder *string `json:"placeholder,omitempty"`
Options map[string]interface{} `json:"options,omitempty"`
Value interface{} `json:"value,omitempty"`
Rules []ValidationRule `json:"rules,omitempty"`
}
FieldUpdate, bağımlılık değişikliklerine göre bir alana uygulanacak güncellemeleri temsil eder.
Genel Bakış ¶
Bu struct, form alanlarının dinamik davranışını kontrol etmek için kullanılır. Bir alanın görünürlüğünden validasyon kurallarına kadar tüm özelliklerini değiştirmeye olanak tanır. Pointer kullanımı sayesinde sadece değiştirilmek istenen özellikler güncellenir, diğerleri mevcut hallerini korur.
Struct Alanları ¶
- `Visible`: Alanın görünür olup olmadığını kontrol eder (nil = değişiklik yok) - `ReadOnly`: Alanın salt okunur olup olmadığını kontrol eder (nil = değişiklik yok) - `Required`: Alanın zorunlu olup olmadığını kontrol eder (nil = değişiklik yok) - `Disabled`: Alanın devre dışı olup olmadığını kontrol eder (nil = değişiklik yok) - `HelpText`: Alanın yardım metnini günceller (nil = değişiklik yok) - `Placeholder`: Alanın placeholder metnini günceller (nil = değişiklik yok) - `Options`: Alanın seçeneklerini günceller (select, radio vb. için) - `Value`: Alanın değerini programatik olarak ayarlar - `Rules`: Alanın validasyon kurallarını günceller
Kullanım Senaryoları ¶
- **Koşullu Görünürlük**: Bir alanı belirli koşullarda göster/gizle - **Dinamik Validasyon**: Koşullara göre validasyon kurallarını değiştir - **Cascade Seçenekler**: Üst seçime göre alt seçenekleri filtrele - **Koşullu Zorunluluk**: Belirli durumlarda alanı zorunlu yap - **Dinamik Değer Atama**: Hesaplanan değerleri alanlara otomatik ata - **Kullanıcı Rehberliği**: Bağlama göre yardım metinlerini güncelle
Kullanım Örneği ¶
```go // Basit görünürlük kontrolü update := NewFieldUpdate().Show().MakeRequired()
// Çoklu özellik güncelleme (method chaining) update := NewFieldUpdate().
Show().
MakeRequired().
SetHelpText("Bu alan zorunludur").
SetPlaceholder("Lütfen bir değer girin")
// Dinamik seçenekler güncelleme
cities := map[string]interface{}{
"istanbul": "İstanbul",
"ankara": "Ankara",
"izmir": "İzmir",
}
update := NewFieldUpdate().SetOptions(cities)
// Validasyon kuralları ekleme update := NewFieldUpdate().
MakeRequired().
AddRule(ValidationRule{Type: "min", Value: 18}).
AddRule(ValidationRule{Type: "max", Value: 65})
// Değer atama ve salt okunur yapma update := NewFieldUpdate().
SetValue("Otomatik hesaplanan değer").
MakeReadOnly()
```
Önemli Notlar ¶
- **Pointer Kullanımı**: Tüm boolean ve string alanlar pointer'dır. Bu sayede nil değer "değişiklik yok" anlamına gelir, false/true veya boş string ile karıştırılmaz
- **Method Chaining**: Tüm setter metodlar *FieldUpdate döndürür, bu sayede zincirleme çağrılar yapılabilir
- **Seçici Güncelleme**: Sadece set edilen alanlar güncellenir, diğerleri korunur
- **JSON Serileştirme**: omitempty tag'leri sayesinde nil alanlar JSON'a dahil edilmez
- **Thread Safety**: Bu struct thread-safe değildir, concurrent kullanımda dikkatli olunmalıdır
Avantajlar ¶
- Esnek ve güçlü alan kontrolü sağlar - Method chaining ile okunabilir kod yazılmasını sağlar - Seçici güncelleme ile performans optimizasyonu sağlar - Type-safe alan güncellemeleri yapar - JSON serileştirme desteği ile API entegrasyonu kolaydır
Dezavantajlar ¶
- Pointer kullanımı nil kontrollerini gerektirir - Karmaşık güncellemelerde kod okunabilirliği azalabilir - Thread-safe değildir
Best Practices ¶
- Her zaman NewFieldUpdate() ile yeni instance oluşturun - Method chaining kullanarak okunabilir kod yazın - Nil kontrollerini ihmal etmeyin - Gereksiz güncellemelerden kaçının (performans için)
func NewFieldUpdate ¶
func NewFieldUpdate() *FieldUpdate
NewFieldUpdate, yeni bir FieldUpdate instance'ı oluşturur.
Genel Bakış ¶
Bu fonksiyon, FieldUpdate struct'ının yeni bir instance'ını oluşturur ve döndürür. Tüm alanlar nil/boş değerlerle başlatılır, bu sayede sadece set edilen özellikler güncelleme sırasında uygulanır.
Kullanım Senaryoları ¶
- Bağımlılık callback fonksiyonlarında yeni güncelleme nesnesi oluşturmak - Method chaining ile zincirleme güncelleme işlemleri yapmak - Temiz ve okunabilir kod yazmak için başlangıç noktası
Dönüş Değeri ¶
`*FieldUpdate`: Yeni oluşturulmuş, boş bir FieldUpdate pointer'ı
Kullanım Örneği ¶
```go // Basit kullanım update := NewFieldUpdate() update.Show() update.MakeRequired()
// Method chaining ile kullanım (önerilen) update := NewFieldUpdate().
Show().
MakeRequired().
SetHelpText("Bu alan zorunludur")
// Bağımlılık callback'inde kullanım
field.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
if formData["country"] == "TR" {
return NewFieldUpdate().Show().MakeRequired()
}
return NewFieldUpdate().Hide()
})
```
Önemli Notlar ¶
- Her güncelleme işlemi için yeni bir instance oluşturun, mevcut instance'ları yeniden kullanmayın - Method chaining kullanarak daha okunabilir kod yazabilirsiniz - Nil döndürmek yerine boş FieldUpdate döndürmek güvenlidir (hiçbir güncelleme yapılmaz)
Best Practices ¶
- Her zaman bu fonksiyonu kullanarak yeni instance oluşturun - Struct literal kullanmak yerine bu factory fonksiyonunu tercih edin - Method chaining ile zincirleme çağrılar yapın
func (*FieldUpdate) AddRule ¶
func (u *FieldUpdate) AddRule(rule ValidationRule) *FieldUpdate
AddRule, mevcut validasyon kurallarına yeni bir kural ekler.
Genel Bakış ¶
Bu metod, bir form alanının mevcut validasyon kurallarına yeni bir kural ekler. Mevcut kuralları korur ve sonuna yeni kuralı ekler. Method chaining desteği için *FieldUpdate döndürür. Kademeli kural ekleme senaryoları için idealdir.
Kullanım Senaryoları ¶
- **Kademeli Kural Ekleme**: Koşullara göre adım adım kural ekle - **Ek Validasyon**: Mevcut kurallara ek kontroller ekle - **Koşullu Kural Ekleme**: Belirli durumlarda ekstra kurallar ekle - **Dinamik Kural Biriktirme**: Birden fazla koşula göre kuralları biriktir - **Modüler Validasyon**: Her koşul için ayrı kural ekle
Parametreler ¶
- `rule`: Eklenecek ValidationRule - Tek bir validasyon kuralı
Dönüş Değeri ¶
`*FieldUpdate`: Method chaining için güncellenmiş FieldUpdate pointer'ı
Kullanım Örneği ¶
```go // Basit kullanım update := NewFieldUpdate().
AddRule(ValidationRule{Type: "required", Message: "Bu alan zorunludur"}).
AddRule(ValidationRule{Type: "min", Value: 3, Message: "En az 3 karakter"})
// Koşullu kural ekleme
passwordField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
update := NewFieldUpdate().
AddRule(ValidationRule{Type: "required", Message: "Şifre zorunludur"}).
AddRule(ValidationRule{Type: "min", Value: 8, Message: "En az 8 karakter"})
// Güvenlik seviyesine göre ek kurallar
securityLevel := formData["security_level"].(string)
if securityLevel == "high" {
update.
AddRule(ValidationRule{Type: "uppercase", Message: "En az 1 büyük harf"}).
AddRule(ValidationRule{Type: "lowercase", Message: "En az 1 küçük harf"}).
AddRule(ValidationRule{Type: "number", Message: "En az 1 rakam"}).
AddRule(ValidationRule{Type: "special", Message: "En az 1 özel karakter"})
} else if securityLevel == "medium" {
update.
AddRule(ValidationRule{Type: "uppercase", Message: "En az 1 büyük harf"}).
AddRule(ValidationRule{Type: "number", Message: "En az 1 rakam"})
}
return update
})
// Kademeli kural ekleme
emailField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
update := NewFieldUpdate().
AddRule(ValidationRule{Type: "required", Message: "E-posta zorunludur"}).
AddRule(ValidationRule{Type: "email", Message: "Geçerli bir e-posta girin"})
// Kurumsal hesap kontrolü
accountType := formData["account_type"].(string)
if accountType == "corporate" {
update.AddRule(ValidationRule{
Type: "domain_whitelist",
Value: []string{"company.com", "partner.com"},
Message: "Sadece şirket e-postaları kabul edilir",
})
}
// Benzersizlik kontrolü
checkUnique := formData["check_unique"].(bool)
if checkUnique {
update.AddRule(ValidationRule{
Type: "unique",
Table: "users",
Column: "email",
Message: "Bu e-posta zaten kullanılıyor",
})
}
return update
})
// Çoklu koşullu kural ekleme
priceField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
update := NewFieldUpdate().
AddRule(ValidationRule{Type: "required", Message: "Fiyat zorunludur"}).
AddRule(ValidationRule{Type: "numeric", Message: "Geçerli bir sayı girin"}).
AddRule(ValidationRule{Type: "min", Value: 0, Message: "Fiyat negatif olamaz"})
// Ürün tipine göre
productType := formData["product_type"].(string)
if productType == "premium" {
update.AddRule(ValidationRule{
Type: "min",
Value: 1000,
Message: "Premium ürünler minimum 1000 TL olmalıdır",
})
}
// Kullanıcı rolüne göre
userRole := ctx.Locals("user_role").(string)
if userRole != "admin" {
update.AddRule(ValidationRule{
Type: "max",
Value: 10000,
Message: "Maksimum 10.000 TL girebilirsiniz",
})
}
// İndirim varsa
hasDiscount := formData["has_discount"].(bool)
if hasDiscount {
update.AddRule(ValidationRule{
Type: "custom",
Value: "validate_discount_price",
Message: "İndirimli fiyat normal fiyattan düşük olmalıdır",
})
}
return update
})
// Method chaining ile zincirleme ekleme update := NewFieldUpdate().
MakeRequired().
AddRule(ValidationRule{Type: "min", Value: 3, Message: "En az 3 karakter"}).
AddRule(ValidationRule{Type: "max", Value: 50, Message: "En fazla 50 karakter"}).
AddRule(ValidationRule{Type: "alphanumeric", Message: "Sadece harf ve rakam"}).
SetHelpText("Kullanıcı adı 3-50 karakter, harf ve rakam içermelidir")
// Dinamik kural biriktirme
ageField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
update := NewFieldUpdate().
AddRule(ValidationRule{Type: "required", Message: "Yaş zorunludur"}).
AddRule(ValidationRule{Type: "numeric", Message: "Geçerli bir sayı girin"})
// Yaş aralığı kontrolü
serviceType := formData["service_type"].(string)
switch serviceType {
case "child":
update.
AddRule(ValidationRule{Type: "min", Value: 0, Message: "Yaş 0'dan küçük olamaz"}).
AddRule(ValidationRule{Type: "max", Value: 12, Message: "Çocuk servisi 0-12 yaş arası"})
case "teen":
update.
AddRule(ValidationRule{Type: "min", Value: 13, Message: "Genç servisi 13 yaşından başlar"}).
AddRule(ValidationRule{Type: "max", Value: 17, Message: "Genç servisi 13-17 yaş arası"})
case "adult":
update.
AddRule(ValidationRule{Type: "min", Value: 18, Message: "Yetişkin servisi 18 yaşından başlar"}).
AddRule(ValidationRule{Type: "max", Value: 65, Message: "Yetişkin servisi 18-65 yaş arası"})
case "senior":
update.
AddRule(ValidationRule{Type: "min", Value: 65, Message: "Yaşlı servisi 65 yaşından başlar"}).
AddRule(ValidationRule{Type: "max", Value: 120, Message: "Geçerli bir yaş girin"})
}
return update
})
```
Önemli Notlar ¶
- **Mevcut Kuralları Korur**: AddRule() mevcut kuralları korur ve sonuna ekler - **Sıralama**: Kurallar eklenme sırasına göre uygulanır - **Çoklu Çağrı**: Birden fazla kez çağrılabilir (method chaining) - **Performans**: Her çağrı slice'a append yapar - **Nil Kontrol**: Rules nil ise otomatik olarak initialize edilir
Best Practices ¶
- Temel kuralları önce ekleyin (required, type checks) - Detaylı kuralları sonra ekleyin (min, max, pattern) - Pahalı kuralları en sona ekleyin (unique, custom validators) - Method chaining kullanarak okunabilir kod yazın - Koşullu ekleme için if blokları kullanın - Kullanıcı dostu hata mesajları yazın
Avantajlar ¶
- Mevcut kuralları korur - Esnek ve modüler kural ekleme - Method chaining desteği - Koşullu kural ekleme için ideal - Okunabilir kod yazımı
Dezavantajlar ¶
- Çok fazla çağrı performansı etkileyebilir - Kural sırası önemlidir (dikkatli olunmalı) - Duplicate kural kontrolü yoktur
AddRule vs SetRules Karşılaştırması ¶
| Özellik | AddRule | SetRules | |---------|---------|----------| | Mevcut Kurallar | Korur ve ekler | Siler ve değiştirir | | Kullanım | Tekli ekleme | Toplu güncelleme | | Method Chaining | Evet | Evet | | Esneklik | Yüksek | Düşük | | Performans | Her çağrıda append | Tek seferde | | Kullanım Amacı | Kademeli ekleme | Tüm kuralları değiştir |
Performans İpuçları ¶
- Çok fazla AddRule çağrısı yerine SetRules kullanmayı düşünün - Pahalı validasyonları (DB sorguları) en sona ekleyin - Gereksiz kural eklemekten kaçının - Kural sayısını makul seviyede tutun (ideal: 3-7 kural)
func (*FieldUpdate) Disable ¶
func (u *FieldUpdate) Disable() *FieldUpdate
Disable, alanı devre dışı bırakır (pasif hale getirir).
Genel Bakış ¶
Bu metod, bir form alanını devre dışı bırakır. Disabled özelliğini true olarak ayarlar ve method chaining desteği için *FieldUpdate döndürür. Devre dışı alanlar kullanıcı tarafından düzenlenemez ve form submit edildiğinde değerleri gönderilmez.
Kullanım Senaryoları ¶
- **Koşullu Devre Dışı Bırakma**: Belirli koşullarda alanları pasif hale getir - **Bağımlılık Kontrolü**: Bağımlı alanları koşul sağlanmadığında devre dışı bırak - **Yetki Kısıtlaması**: Yetkisiz kullanıcılar için alanları kapat - **İş Kuralları**: İş mantığına göre alanları devre dışı bırak - **Geçici Kilitleme**: Belirli durumlarda alanları geçici olarak kilitle
Dönüş Değeri ¶
`*FieldUpdate`: Method chaining için güncellenmiş FieldUpdate pointer'ı
Kullanım Örneği ¶
```go // Basit kullanım update := NewFieldUpdate().Disable()
// Bağımlılık kontrolü
countryField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
country := formData["country"]
if country == "" {
// Ülke seçilmediğinde şehir alanını devre dışı bırak
return NewFieldUpdate().
Disable().
SetHelpText("Önce ülke seçin").
SetValue(nil)
}
return NewFieldUpdate().Enable()
})
// Yetki kısıtlaması userRole := ctx.Locals("user_role").(string)
if userRole == "viewer" {
return NewFieldUpdate().
Disable().
SetHelpText("Bu alanı düzenleme yetkiniz yok")
}
// İş kuralı bazlı devre dışı bırakma
statusField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
status := formData["status"]
if status == "completed" {
// Tamamlanmış kayıtlar düzenlenemez
return NewFieldUpdate().
Disable().
MakeReadOnly().
SetHelpText("Tamamlanmış kayıtlar düzenlenemez")
}
return NewFieldUpdate().Enable().MakeEditable()
})
// Koşullu form akışı
paymentMethodField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
paymentMethod := formData["payment_method"]
if paymentMethod == "cash" {
// Nakit ödeme için kredi kartı alanlarını devre dışı bırak
return NewFieldUpdate().
Disable().
Hide().
SetValue(nil)
}
return NewFieldUpdate().Enable().Show()
})
// Geçici kilitleme
processingField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
isProcessing := formData["is_processing"].(bool)
if isProcessing {
return NewFieldUpdate().
Disable().
SetHelpText("İşlem devam ediyor, lütfen bekleyin...")
}
return NewFieldUpdate().Enable()
})
```
Önemli Notlar ¶
- **Form Submit**: Disabled alanların değerleri form submit edildiğinde gönderilmez - **Validasyon**: Disabled alanlar için validasyon kuralları uygulanmaz - **Görünürlük**: Disable() sadece disabled durumunu değiştirir, görünürlüğü etkilemez - **Değer Temizleme**: Devre dışı bırakılan alanların değerlerini SetValue(nil) ile temizlemeyi düşünün - **Kullanıcı Deneyimi**: Neden devre dışı olduğunu açıklayan yardım metni ekleyin
Best Practices ¶
- Disable() ile birlikte SetHelpText() kullanarak kullanıcıyı bilgilendirin - Devre dışı bırakılan alanların değerlerini temizlemeyi düşünün - Hide() ile birlikte kullanarak gereksiz alanları tamamen gizleyin - Koşullu devre dışı bırakmada her iki durumu da (Enable/Disable) ele alın - Sunucu tarafında da aynı kontrolü uygulayın (güvenlik)
Avantajlar ¶
- Kullanıcı hatalarını önler - Form akışını kontrol eder - Bağımlılık yönetimini kolaylaştırır - Kullanıcı deneyimini iyileştirir
Dezavantajlar ¶
- Disabled alanların değerleri form submit'e dahil edilmez (veri kaybı riski) - Aşırı kullanımda kullanıcı deneyimini olumsuz etkiler
func (*FieldUpdate) Enable ¶
func (u *FieldUpdate) Enable() *FieldUpdate
Enable, alanı etkinleştirir (aktif hale getirir).
Genel Bakış ¶
Bu metod, devre dışı bırakılmış bir alanı tekrar etkinleştirir. Disabled özelliğini false olarak ayarlar ve method chaining desteği için *FieldUpdate döndürür. Etkin alanlar kullanıcı tarafından düzenlenebilir ve form submit edildiğinde değerleri gönderilir.
Kullanım Senaryoları ¶
- **Koşullu Aktivasyon**: Belirli koşullarda alanları aktif hale getir - **Adım Bazlı Formlar**: Form adımlarına göre alanları etkinleştir - **Yetki Bazlı Erişim**: Kullanıcı yetkisine göre alanları aktif et - **Dinamik Form Akışı**: Kullanıcı seçimlerine göre alanları etkinleştir - **Bağımlılık Çözümü**: Bağımlı alanları koşul sağlandığında aktif et
Dönüş Değeri ¶
`*FieldUpdate`: Method chaining için güncellenmiş FieldUpdate pointer'ı
Kullanım Örneği ¶
```go // Basit kullanım update := NewFieldUpdate().Enable()
// Koşullu aktivasyon
agreementField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
agreed := formData["terms_agreed"].(bool)
if agreed {
// Sözleşme kabul edildiğinde devam butonu aktif
return NewFieldUpdate().
Enable().
SetHelpText("Devam edebilirsiniz")
}
return NewFieldUpdate().
Disable().
SetHelpText("Devam etmek için sözleşmeyi kabul edin")
})
// Bağımlılık çözümü
countryField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
country := formData["country"]
if country != "" {
// Ülke seçildiğinde şehir alanını aktif et
return NewFieldUpdate().
Enable().
Show().
SetHelpText("Lütfen şehir seçin")
}
return NewFieldUpdate().Disable().Hide()
})
// Adım bazlı form
stepField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
step := formData["current_step"].(int)
if step >= 2 {
// 2. adımda ödeme alanlarını aktif et
return NewFieldUpdate().
Enable().
Show().
MakeRequired()
}
return NewFieldUpdate().Disable().Hide()
})
// Yetki bazlı erişim userRole := ctx.Locals("user_role").(string)
if userRole == "admin" || userRole == "editor" {
return NewFieldUpdate().
Enable().
MakeEditable().
SetHelpText("Düzenleme yetkisine sahipsiniz")
}
```
Önemli Notlar ¶
- **Disabled vs ReadOnly**: Disabled alanlar form submit'e dahil edilmez, ReadOnly alanlar dahil edilir - **Görünürlük**: Enable() sadece disabled durumunu değiştirir, görünürlüğü etkilemez - **Validasyon**: Etkin alanlar için validasyon kuralları uygulanır - **Form Submit**: Etkin alanların değerleri form submit edildiğinde gönderilir - **Method Chaining**: Diğer metodlarla zincirleme kullanılabilir
Best Practices ¶
- Enable() ile birlikte Show() kullanarak tam erişim sağlayın - Etkinleştirilen alanlar için uygun yardım metni ekleyin - MakeEditable() ile birlikte kullanarak düzenleme izni verin - Koşullu aktivasyonda her iki durumu da (Enable/Disable) ele alın
Avantajlar ¶
- Dinamik form davranışı sağlar - Kullanıcı deneyimini iyileştirir - Bağımlılık yönetimini kolaylaştırır - Koşullu erişim kontrolü sağlar
Disabled vs ReadOnly Karşılaştırması ¶
| Özellik | Disabled | ReadOnly | |---------|----------|----------| | Görünürlük | Görünür (genelde soluk) | Görünür (normal) | | Düzenlenebilirlik | Hayır | Hayır | | Form Submit | Dahil edilmez | Dahil edilir | | Validasyon | Uygulanmaz | Uygulanmaz | | Kullanım Amacı | Geçici devre dışı | Kalıcı koruma |
func (*FieldUpdate) Hide ¶
func (u *FieldUpdate) Hide() *FieldUpdate
Hide, alanı gizler.
Genel Bakış ¶
Bu metod, bir form alanının kullanıcı arayüzünde gizlenmesini sağlar. Visible özelliğini false olarak ayarlar ve method chaining desteği için *FieldUpdate döndürür.
Kullanım Senaryoları ¶
- Koşullu alan gizleme: Belirli bir değer seçildiğinde ilgisiz alanları gizle - Dinamik form yapısı: Kullanıcı seçimlerine göre gereksiz alanları gizle - Basitleştirilmiş form: Kullanıcıya sadece ilgili alanları göster - Validasyon atlama: Gizli alanlar için validasyon uygulanmaz
Dönüş Değeri ¶
`*FieldUpdate`: Method chaining için güncellenmiş FieldUpdate pointer'ı
Kullanım Örneği ¶
```go // Basit kullanım update := NewFieldUpdate().Hide()
// Koşullu gizleme
if formData["payment_method"] == "cash" {
// Nakit ödeme seçildiğinde kredi kartı alanlarını gizle
return NewFieldUpdate().Hide().MakeOptional()
}
// Karmaşık koşullu mantık
productTypeField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
productType := formData["product_type"]
if productType == "digital" {
// Dijital ürünler için fiziksel ürün alanlarını gizle
return NewFieldUpdate().Hide().MakeOptional().SetValue(nil)
}
return NewFieldUpdate().Show().MakeRequired()
})
// Method chaining ile birlikte kullanım update := NewFieldUpdate().
Hide(). MakeOptional(). SetValue(nil) // Gizli alan için değeri temizle
```
Önemli Notlar ¶
- Hide() çağrıldığında alan gizlenir ve validasyon kuralları uygulanmaz - Gizli alanların değerleri form submit edildiğinde gönderilmeyebilir - Güvenlik açısından hassas alanlar için Hide() yeterli değildir, sunucu tarafı kontrolü gereklidir - Method chaining desteklenir, zincirleme çağrılar yapılabilir - Gizlenen alanları MakeOptional() ile birlikte kullanmak önerilir
Best Practices ¶
- Hide() ile birlikte MakeOptional() kullanarak validasyon hatalarını önleyin - Gizlenen alanların değerlerini SetValue(nil) ile temizlemeyi düşünün - Koşullu gizlemede her iki durumu da (Show/Hide) ele alın - Güvenlik kritik alanlar için sunucu tarafı kontrolü yapın
func (*FieldUpdate) MakeEditable ¶
func (u *FieldUpdate) MakeEditable() *FieldUpdate
MakeEditable, alanı düzenlenebilir hale getirir.
Genel Bakış ¶
Bu metod, daha önce salt okunur yapılmış bir alanı tekrar düzenlenebilir hale getirir. ReadOnly özelliğini false olarak ayarlar ve method chaining desteği için *FieldUpdate döndürür.
Kullanım Senaryoları ¶
- **Koşullu Düzenleme**: Belirli koşullarda alanları düzenlenebilir yap - **Rol Bazlı Erişim**: Yetki seviyesine göre alanları aç/kapat - **Durum Bazlı Kontrol**: Kayıt durumuna göre düzenleme izni ver - **Dinamik Form**: Kullanıcı seçimlerine göre alanları aktif et
Dönüş Değeri ¶
`*FieldUpdate`: Method chaining için güncellenmiş FieldUpdate pointer'ı
Kullanım Örneği ¶
```go // Basit kullanım update := NewFieldUpdate().MakeEditable()
// Durum bazlı düzenleme
statusField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
status := formData["status"]
if status == "draft" {
// Taslak durumunda tüm alanlar düzenlenebilir
return NewFieldUpdate().
MakeEditable().
SetHelpText("Taslak durumunda düzenleyebilirsiniz")
}
return NewFieldUpdate().
MakeReadOnly().
SetHelpText("Sadece taslak durumunda düzenlenebilir")
})
// Rol bazlı erişim
if ctx.Locals("user_role") == "admin" {
return NewFieldUpdate().
MakeEditable().
SetHelpText("Admin olarak düzenleme yetkisine sahipsiniz")
}
// Koşullu düzenleme
editModeField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
editMode := formData["edit_mode"].(bool)
if editMode {
return NewFieldUpdate().MakeEditable().Enable()
}
return NewFieldUpdate().MakeReadOnly().Disable()
})
```
Önemli Notlar ¶
- MakeEditable() çağrıldığında alan düzenlenebilir olur ancak disabled durumu değişmez - Düzenlenebilir alanlar için validasyon kuralları uygulanır - Sunucu tarafında da aynı yetki kontrolü yapılmalıdır - Method chaining desteklenir
Best Practices ¶
- Düzenleme izni verirken uygun yardım metni ekleyin - Sunucu tarafında yetki kontrolü yapın (güvenlik) - Enable() ile birlikte kullanarak tam erişim sağlayın - Koşullu düzenlemede her iki durumu da (Editable/ReadOnly) ele alın
func (*FieldUpdate) MakeOptional ¶
func (u *FieldUpdate) MakeOptional() *FieldUpdate
MakeOptional, alanı opsiyonel (zorunlu olmayan) hale getirir.
Genel Bakış ¶
Bu metod, daha önce zorunlu yapılmış bir alanı opsiyonel hale getirir. Required özelliğini false olarak ayarlar ve method chaining desteği için *FieldUpdate döndürür.
Kullanım Senaryoları ¶
- **Koşullu Opsiyonellik**: Belirli durumlarda alanları opsiyonel yap - **Basitleştirilmiş Form**: Kullanıcı deneyimini iyileştirmek için gereksiz zorunlulukları kaldır - **Dinamik İş Kuralları**: Koşullara göre zorunluluk durumunu değiştir - **Adım Bazlı Formlar**: Farklı adımlarda farklı zorunluluk seviyeleri
Dönüş Değeri ¶
`*FieldUpdate`: Method chaining için güncellenmiş FieldUpdate pointer'ı
Kullanım Örneği ¶
```go // Basit kullanım update := NewFieldUpdate().MakeOptional()
// Koşullu opsiyonellik
accountTypeField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
accountType := formData["account_type"]
if accountType == "personal" {
// Bireysel hesaplar için şirket adı opsiyonel
return NewFieldUpdate().
MakeOptional().
SetHelpText("Bireysel hesaplar için opsiyonel")
}
return NewFieldUpdate().
MakeRequired().
SetHelpText("Kurumsal hesaplar için zorunlu")
})
// Gizli alanlar için
visibilityField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
visible := formData["show_field"].(bool)
if !visible {
// Gizli alanlar opsiyonel olmalı
return NewFieldUpdate().Hide().MakeOptional()
}
return NewFieldUpdate().Show().MakeRequired()
})
// Basitleştirilmiş form akışı
quickModeField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
quickMode := formData["quick_mode"].(bool)
if quickMode {
// Hızlı mod: detaylı alanlar opsiyonel
return NewFieldUpdate().
MakeOptional().
SetHelpText("Hızlı modda bu alan opsiyoneldir")
}
return NewFieldUpdate().
MakeRequired().
SetHelpText("Detaylı modda bu alan zorunludur")
})
```
Önemli Notlar ¶
- MakeOptional() çağrıldığında alan için validasyon zorunluluğu kaldırılır - Opsiyonel alanlar boş bırakılabilir - Gizli alanlar her zaman opsiyonel yapılmalıdır - Method chaining desteklenir
Best Practices ¶
- Hide() ile birlikte kullanarak tutarlılık sağlayın - Opsiyonel alanlar için açıklayıcı yardım metni ekleyin - Koşullu zorunlulukta her iki durumu da (Required/Optional) ele alın - Kullanıcı deneyimini önceliklendirin
Avantajlar ¶
- Kullanıcı deneyimini iyileştirir - Form doldurma süresini kısaltır - Esnek form yapısı sağlar - Gereksiz zorunlulukları kaldırır
func (*FieldUpdate) MakeReadOnly ¶
func (u *FieldUpdate) MakeReadOnly() *FieldUpdate
MakeReadOnly, alanı salt okunur (read-only) hale getirir.
Genel Bakış ¶
Bu metod, bir form alanının kullanıcı tarafından düzenlenemez ancak görüntülenebilir olmasını sağlar. ReadOnly özelliğini true olarak ayarlar ve method chaining desteği için *FieldUpdate döndürür.
Kullanım Senaryoları ¶
- **Hesaplanan Değerler**: Otomatik hesaplanan alanları göster ancak düzenlemeye izin verme - **Sistem Alanları**: Sistem tarafından yönetilen alanları koruma altına al - **Onay Sonrası Kilitleme**: Onaylanmış kayıtların belirli alanlarını kilitle - **Referans Bilgileri**: Referans amaçlı gösterilen ancak değiştirilmemesi gereken bilgiler - **Audit Trail**: Değişiklik geçmişi için orijinal değerleri koruma
Dönüş Değeri ¶
`*FieldUpdate`: Method chaining için güncellenmiş FieldUpdate pointer'ı
Kullanım Örneği ¶
```go // Basit kullanım update := NewFieldUpdate().MakeReadOnly()
// Hesaplanan toplam alanı
quantityField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
quantity := formData["quantity"].(float64)
price := formData["price"].(float64)
total := quantity * price
// Toplam alanını hesapla ve salt okunur yap
return NewFieldUpdate().
SetValue(total).
MakeReadOnly().
SetHelpText(fmt.Sprintf("Otomatik hesaplanan: %.2f TL", total))
})
// Onaylanmış kayıtlar için
statusField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
status := formData["status"]
if status == "approved" {
// Onaylandıktan sonra fiyat alanını kilitle
return NewFieldUpdate().
MakeReadOnly().
SetHelpText("Onaylanmış kayıtlarda fiyat değiştirilemez")
}
return NewFieldUpdate().MakeEditable()
})
// Sistem alanları createdAtField := NewFieldUpdate().
MakeReadOnly().
SetHelpText("Sistem tarafından otomatik oluşturuldu")
```
Önemli Notlar ¶
- **Görünürlük**: ReadOnly alanlar görünür kalır ancak düzenlenemez - **Validasyon**: ReadOnly alanlar için validasyon kuralları uygulanmaz (değer değişmediği için) - **Form Submit**: ReadOnly alanların değerleri form submit edildiğinde gönderilir - **Güvenlik**: Sunucu tarafında da kontrol yapılmalıdır, sadece client-side koruma yeterli değildir - **Disabled vs ReadOnly**: Disabled alanlar form submit'e dahil edilmez, ReadOnly alanlar dahil edilir
Best Practices ¶
- Hesaplanan değerler için SetValue() ile birlikte kullanın - Kullanıcıya neden düzenleyemediğini açıklayan yardım metni ekleyin - Sunucu tarafında da aynı kontrolü uygulayın (güvenlik) - Geçici kilitleme durumları için koşullu kullanın
func (*FieldUpdate) MakeRequired ¶
func (u *FieldUpdate) MakeRequired() *FieldUpdate
MakeRequired, alanı zorunlu hale getirir.
Genel Bakış ¶
Bu metod, bir form alanının doldurulmasını zorunlu kılar. Required özelliğini true olarak ayarlar ve method chaining desteği için *FieldUpdate döndürür. Zorunlu alanlar için validasyon kuralları otomatik olarak uygulanır.
Kullanım Senaryoları ¶
- **Koşullu Zorunluluk**: Belirli bir seçim yapıldığında ilgili alanları zorunlu yap - **Dinamik Validasyon**: Kullanıcı akışına göre zorunlu alanları değiştir - **İş Kuralları**: İş mantığına göre alanları zorunlu hale getir - **Adım Bazlı Formlar**: Her adımda farklı alanları zorunlu yap - **Rol Bazlı Zorunluluk**: Kullanıcı rolüne göre zorunlu alanları belirle
Dönüş Değeri ¶
`*FieldUpdate`: Method chaining için güncellenmiş FieldUpdate pointer'ı
Kullanım Örneği ¶
```go // Basit kullanım update := NewFieldUpdate().MakeRequired()
// Koşullu zorunluluk
shippingTypeField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
shippingType := formData["shipping_type"]
if shippingType == "express" {
// Ekspres kargo için telefon numarası zorunlu
return NewFieldUpdate().
Show().
MakeRequired().
SetHelpText("Ekspres kargo için telefon numarası zorunludur")
}
return NewFieldUpdate().MakeOptional()
})
// İş kuralı bazlı zorunluluk
companyField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
hasCompany := formData["has_company"].(bool)
if hasCompany {
// Şirket varsa vergi numarası zorunlu
return NewFieldUpdate().
Show().
MakeRequired().
SetHelpText("Kurumsal müşteriler için vergi numarası zorunludur").
SetPlaceholder("10 haneli vergi numarası")
}
return NewFieldUpdate().Hide().MakeOptional()
})
// Çoklu alan kontrolü
paymentMethodField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
paymentMethod := formData["payment_method"]
if paymentMethod == "credit_card" {
// Kredi kartı seçildiğinde kart bilgileri zorunlu
return NewFieldUpdate().
Show().
MakeRequired().
AddRule(ValidationRule{Type: "credit_card"})
}
return NewFieldUpdate().Hide().MakeOptional()
})
// Rol bazlı zorunluluk userRole := ctx.Locals("user_role").(string)
if userRole == "premium" {
return NewFieldUpdate().
MakeRequired().
SetHelpText("Premium üyeler için bu alan zorunludur")
}
```
Önemli Notlar ¶
- **Validasyon**: Zorunlu alanlar boş bırakıldığında validasyon hatası verir - **Görünürlük**: Gizli alanlar zorunlu yapılsa bile validasyon uygulanmaz - **Kullanıcı Deneyimi**: Zorunlu alanlar için açıklayıcı yardım metni ekleyin - **Form Submit**: Zorunlu alanlar doldurulmadan form submit edilemez - **API Validasyonu**: Sunucu tarafında da aynı zorunluluk kontrolü yapılmalıdır
Best Practices ¶
- Zorunlu alanlar için SetHelpText() ile açıklama ekleyin - Show() ile birlikte kullanarak görünürlüğü sağlayın - Kullanıcıya neden zorunlu olduğunu açıklayın - Sunucu tarafında da validasyon yapın (güvenlik) - Gereksiz zorunluluktan kaçının (kullanıcı deneyimi için)
Avantajlar ¶
- Veri bütünlüğünü sağlar - İş kurallarını zorlar - Kullanıcı hatalarını önler - Dinamik form davranışı sağlar
Dezavantajlar ¶
- Aşırı kullanımda kullanıcı deneyimini olumsuz etkiler - Karmaşık koşullu mantıkta hata yapma riski artar
func (*FieldUpdate) SetHelpText ¶
func (u *FieldUpdate) SetHelpText(text string) *FieldUpdate
SetHelpText, alanın yardım metnini ayarlar.
Genel Bakış ¶
Bu metod, bir form alanının altında veya yanında gösterilen yardım metnini dinamik olarak günceller. HelpText özelliğini verilen string ile ayarlar ve method chaining desteği için *FieldUpdate döndürür. Yardım metinleri kullanıcıya alan hakkında ek bilgi, format gereksinimleri veya örnekler sağlar.
Kullanım Senaryoları ¶
- **Bağlamsal Yardım**: Kullanıcı seçimlerine göre ilgili yardım metni göster - **Format Açıklaması**: Beklenen veri formatını açıkla (örn: "DD/MM/YYYY formatında") - **Validasyon Rehberi**: Validasyon kurallarını kullanıcıya açıkla - **Durum Bildirimi**: Alan durumu hakkında bilgi ver (örn: "Hesaplanıyor...") - **Hata Önleme**: Yaygın hataları önlemek için uyarılar ver - **Örnek Gösterme**: Geçerli değer örnekleri göster
Parametreler ¶
- `text`: Gösterilecek yardım metni (string)
Dönüş Değeri ¶
`*FieldUpdate`: Method chaining için güncellenmiş FieldUpdate pointer'ı
Kullanım Örneği ¶
```go // Basit kullanım update := NewFieldUpdate().SetHelpText("Bu alan zorunludur")
// Bağlamsal yardım
countryField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
country := formData["country"]
if country == "TR" {
return NewFieldUpdate().
SetHelpText("11 haneli TC Kimlik Numaranızı girin (örn: 12345678901)")
} else if country == "US" {
return NewFieldUpdate().
SetHelpText("9 haneli SSN numaranızı girin (örn: 123-45-6789)")
}
return NewFieldUpdate().SetHelpText("Kimlik numaranızı girin")
})
// Format açıklaması
dateField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
return NewFieldUpdate().
SetHelpText("Tarih formatı: GG/AA/YYYY (örn: 15/03/2024)")
})
// Validasyon rehberi
passwordField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
return NewFieldUpdate().
SetHelpText("En az 8 karakter, 1 büyük harf, 1 küçük harf ve 1 rakam içermelidir")
})
// Durum bildirimi
calculatingField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
isCalculating := formData["is_calculating"].(bool)
if isCalculating {
return NewFieldUpdate().
SetHelpText("⏳ Hesaplama yapılıyor, lütfen bekleyin...").
Disable()
}
return NewFieldUpdate().
SetHelpText("Toplam tutar otomatik hesaplanmıştır").
Enable()
})
// Koşullu uyarı
amountField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
amount := formData["amount"].(float64)
if amount > 10000 {
return NewFieldUpdate().
SetHelpText("⚠️ Yüksek tutar: Ek onay gerekebilir")
}
return NewFieldUpdate().SetHelpText("Tutar giriniz")
})
// Çoklu dil desteği language := ctx.Locals("language").(string)
if language == "tr" {
return NewFieldUpdate().SetHelpText("E-posta adresinizi girin")
} else {
return NewFieldUpdate().SetHelpText("Enter your email address")
}
```
Önemli Notlar ¶
- **Markdown Desteği**: Bazı UI framework'leri markdown formatını destekleyebilir - **Uzunluk**: Yardım metinleri kısa ve öz olmalıdır (ideal: 1-2 cümle) - **Emoji Kullanımı**: Dikkat çekmek için emoji kullanılabilir ancak aşırıya kaçılmamalı - **Dinamik Güncelleme**: Yardım metni form durumuna göre dinamik olarak güncellenebilir - **Erişilebilirlik**: Screen reader'lar için anlamlı metinler yazın
Best Practices ¶
- Kısa, açık ve anlaşılır metinler yazın - Örnekler vererek kullanıcıyı yönlendirin - Hata mesajları yerine önleyici bilgiler verin - Teknik jargondan kaçının, sade dil kullanın - Çoklu dil desteği için i18n kullanmayı düşünün - Kullanıcının mevcut bağlamına uygun metinler gösterin
Avantajlar ¶
- Kullanıcı deneyimini iyileştirir - Hata oranını azaltır - Form doldurma süresini kısaltır - Kullanıcı güvenini artırır - Destek taleplerini azaltır
func (*FieldUpdate) SetOptions ¶
func (u *FieldUpdate) SetOptions(options map[string]interface{}) *FieldUpdate
SetOptions, alanın seçeneklerini ayarlar (select, radio, checkbox gibi alanlar için).
Genel Bakış ¶
Bu metod, select, radio button, checkbox gibi seçim alanlarının seçeneklerini dinamik olarak günceller. Options özelliğini verilen map ile ayarlar ve method chaining desteği için *FieldUpdate döndürür. Bu özellik, cascade dropdown'lar ve dinamik seçim listeleri için kritik öneme sahiptir.
Kullanım Senaryoları ¶
- **Cascade Dropdown**: Üst seçime göre alt dropdown seçeneklerini filtrele - **Dinamik Seçenekler**: Kullanıcı seçimlerine göre seçenekleri değiştir - **Veritabanı Sorguları**: Context üzerinden veritabanından seçenekleri çek - **Koşullu Seçenekler**: İş kurallarına göre farklı seçenekler göster - **Filtrelenmiş Listeler**: Belirli kriterlere göre seçenekleri filtrele - **Rol Bazlı Seçenekler**: Kullanıcı rolüne göre farklı seçenekler sun
Parametreler ¶
- `options`: Seçenekleri içeren map[string]interface{}
- Key: Seçeneğin değeri (value)
- Value: Seçeneğin görünen metni (label) veya karmaşık nesne
Dönüş Değeri ¶
`*FieldUpdate`: Method chaining için güncellenmiş FieldUpdate pointer'ı
Kullanım Örneği ¶
```go // Basit kullanım
cities := map[string]interface{}{
"istanbul": "İstanbul",
"ankara": "Ankara",
"izmir": "İzmir",
}
update := NewFieldUpdate().SetOptions(cities)
// Cascade dropdown - Ülkeye göre şehirler
countryField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
country := formData["country"].(string)
var cities map[string]interface{}
switch country {
case "TR":
cities = map[string]interface{}{
"istanbul": "İstanbul",
"ankara": "Ankara",
"izmir": "İzmir",
"bursa": "Bursa",
}
case "US":
cities = map[string]interface{}{
"new_york": "New York",
"los_angeles": "Los Angeles",
"chicago": "Chicago",
}
default:
cities = map[string]interface{}{}
}
return NewFieldUpdate().
SetOptions(cities).
Show().
Enable().
SetValue(nil) // Önceki seçimi temizle
})
// Veritabanından dinamik seçenekler
categoryField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
categoryID := formData["category_id"].(int)
// Veritabanından alt kategorileri çek
var subcategories []Subcategory
db := ctx.Locals("db").(*gorm.DB)
db.Where("category_id = ?", categoryID).Find(&subcategories)
// Map'e dönüştür
options := make(map[string]interface{})
for _, sub := range subcategories {
options[fmt.Sprintf("%d", sub.ID)] = sub.Name
}
return NewFieldUpdate().
SetOptions(options).
Show().
MakeRequired().
SetHelpText(fmt.Sprintf("%d alt kategori bulundu", len(options)))
})
// Karmaşık seçenek nesneleri
productField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
options := map[string]interface{}{
"1": map[string]interface{}{
"label": "Premium Paket",
"price": 1000,
"description": "Tüm özellikler dahil",
"icon": "star",
},
"2": map[string]interface{}{
"label": "Standart Paket",
"price": 500,
"description": "Temel özellikler",
"icon": "check",
},
}
return NewFieldUpdate().SetOptions(options)
})
// Filtrelenmiş seçenekler
priceRangeField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
priceRange := formData["price_range"].(string)
var products []Product
db := ctx.Locals("db").(*gorm.DB)
switch priceRange {
case "low":
db.Where("price < ?", 100).Find(&products)
case "medium":
db.Where("price BETWEEN ? AND ?", 100, 500).Find(&products)
case "high":
db.Where("price > ?", 500).Find(&products)
}
options := make(map[string]interface{})
for _, p := range products {
options[fmt.Sprintf("%d", p.ID)] = fmt.Sprintf("%s - %.2f TL", p.Name, p.Price)
}
return NewFieldUpdate().SetOptions(options)
})
// Rol bazlı seçenekler userRole := ctx.Locals("user_role").(string) var statusOptions map[string]interface{}
if userRole == "admin" {
statusOptions = map[string]interface{}{
"draft": "Taslak",
"pending": "Beklemede",
"approved": "Onaylandı",
"rejected": "Reddedildi",
"archived": "Arşivlendi",
}
} else {
statusOptions = map[string]interface{}{
"draft": "Taslak",
"pending": "Beklemede",
}
}
return NewFieldUpdate().SetOptions(statusOptions) ```
Önemli Notlar ¶
- **Map Formatı**: Key-value çiftleri şeklinde olmalıdır - **Değer Temizleme**: Seçenekler değiştiğinde mevcut değeri SetValue(nil) ile temizleyin - **Performans**: Büyük seçenek listeleri için pagination veya lazy loading düşünün - **Veritabanı Sorguları**: Context üzerinden DB erişimi yapılabilir ancak performans etkileri göz önünde bulundurulmalıdır - **Boş Seçenekler**: Boş map göndermek seçenekleri temizler
Best Practices ¶
- Cascade dropdown'larda üst seçim değiştiğinde alt seçimi temizleyin - Veritabanı sorgularını optimize edin (index, limit kullanın) - Büyük listelerde arama/filtreleme özelliği ekleyin - Seçenek sayısını kullanıcıya bildirin (yardım metni ile) - Hata durumlarını ele alın (veritabanı hatası, boş sonuç vb.) - Cache mekanizması kullanarak performansı artırın
Avantajlar ¶
- Dinamik ve esnek seçim listeleri sağlar - Cascade dropdown'ları kolayca uygular - Kullanıcı deneyimini iyileştirir - İş kurallarını kolayca uygular - Veritabanı entegrasyonu kolaydır
Dezavantajlar ¶
- Büyük seçenek listeleri performans sorunlarına yol açabilir - Veritabanı sorguları her değişiklikte çalışabilir (performans) - Karmaşık bağımlılık zincirleri debug edilmesi zor olabilir
Performans İpuçları ¶
- Veritabanı sorgularını cache'leyin - Lazy loading kullanın (büyük listeler için) - Pagination ekleyin (1000+ seçenek için) - Debounce mekanizması kullanın (arama için) - Index'leri optimize edin
func (*FieldUpdate) SetPlaceholder ¶
func (u *FieldUpdate) SetPlaceholder(text string) *FieldUpdate
SetPlaceholder, alanın placeholder (yer tutucu) metnini ayarlar.
Genel Bakış ¶
Bu metod, bir form alanının içinde gösterilen placeholder metnini dinamik olarak günceller. Placeholder özelliğini verilen string ile ayarlar ve method chaining desteği için *FieldUpdate döndürür. Placeholder metinleri, alan boşken kullanıcıya ne girmesi gerektiği hakkında ipucu verir.
Kullanım Senaryoları ¶
- **Format Örneği**: Beklenen format için örnek göster (örn: "ö[email protected]") - **Değer Önerisi**: Tipik değer örnekleri göster (örn: "Ahmet Yılmaz") - **Arama İpucu**: Arama alanlarında ne aranabileceğini göster - **Dinamik İpuçları**: Kullanıcı seçimlerine göre farklı örnekler göster - **Birim Belirtme**: Sayısal alanlar için birim göster (örn: "0.00 TL")
Parametreler ¶
- `text`: Gösterilecek placeholder metni (string)
Dönüş Değeri ¶
`*FieldUpdate`: Method chaining için güncellenmiş FieldUpdate pointer'ı
Kullanım Örneği ¶
```go // Basit kullanım update := NewFieldUpdate().SetPlaceholder("Adınızı girin")
// Format örneği emailField := NewFieldUpdate().
SetPlaceholder("[email protected]").
SetHelpText("Geçerli bir e-posta adresi girin")
// Dinamik placeholder
searchTypeField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
searchType := formData["search_type"]
switch searchType {
case "name":
return NewFieldUpdate().SetPlaceholder("Örn: Ahmet Yılmaz")
case "email":
return NewFieldUpdate().SetPlaceholder("Örn: [email protected]")
case "phone":
return NewFieldUpdate().SetPlaceholder("Örn: 0532 123 45 67")
default:
return NewFieldUpdate().SetPlaceholder("Arama...")
}
})
// Birim belirtme priceField := NewFieldUpdate().
SetPlaceholder("0.00 TL").
SetHelpText("Ürün fiyatını girin")
// Bağlamsal örnek
countryField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
country := formData["country"]
if country == "TR" {
return NewFieldUpdate().
SetPlaceholder("İstanbul, Ankara, İzmir...").
SetHelpText("Türkiye'deki bir şehir seçin")
} else if country == "US" {
return NewFieldUpdate().
SetPlaceholder("New York, Los Angeles, Chicago...").
SetHelpText("Select a US city")
}
return NewFieldUpdate().SetPlaceholder("Şehir seçin...")
})
// Arama alanı searchField := NewFieldUpdate().
SetPlaceholder("Ürün adı, kategori veya marka ara...").
SetHelpText("En az 3 karakter girin")
// Sayısal alan quantityField := NewFieldUpdate().
SetPlaceholder("1").
SetHelpText("Sipariş miktarını girin (minimum: 1)")
// Tarih alanı dateField := NewFieldUpdate().
SetPlaceholder("GG/AA/YYYY").
SetHelpText("Doğum tarihinizi girin")
// Çoklu dil desteği language := ctx.Locals("language").(string)
if language == "tr" {
return NewFieldUpdate().SetPlaceholder("Mesajınızı yazın...")
} else {
return NewFieldUpdate().SetPlaceholder("Type your message...")
}
```
Önemli Notlar ¶
- **Görünürlük**: Placeholder sadece alan boşken görünür, değer girildiğinde kaybolur - **Erişilebilirlik**: Placeholder, label'ın yerini tutmamalıdır (her ikisi de olmalı) - **Uzunluk**: Kısa ve öz olmalıdır (ideal: 2-5 kelime) - **Renk**: Genelde soluk renkte gösterilir, asıl değerle karıştırılmamalı - **Validasyon**: Placeholder metni validasyon kuralı değildir, sadece ipucudur
Best Practices ¶
- Gerçekçi ve anlamlı örnekler kullanın - "Örn:" veya "..." gibi önekler ekleyerek placeholder olduğunu belirtin - Label ile tekrar etmeyin, ek bilgi verin - Kısa ve öz tutun (uzun metinler kesilir) - Birim veya format bilgisi içeren örnekler verin - Çoklu dil desteği için i18n kullanın
Placeholder vs HelpText Karşılaştırması ¶
| Özellik | Placeholder | HelpText | |---------|-------------|----------| | Konum | Alan içinde | Alan dışında (altında/yanında) | | Görünürlük | Sadece boşken | Her zaman | | Uzunluk | Kısa (2-5 kelime) | Orta (1-2 cümle) | | Amaç | Örnek göster | Açıklama yap | | Erişilebilirlik | Düşük | Yüksek |
Avantajlar ¶
- Kullanıcıya hızlı ipucu verir - Form alanını temiz tutar - Örnek göstererek anlaşılırlığı artırır - Kullanıcı hatalarını azaltır
func (*FieldUpdate) SetRules ¶
func (u *FieldUpdate) SetRules(rules []ValidationRule) *FieldUpdate
SetRules, alanın validasyon kurallarını ayarlar.
Genel Bakış ¶
Bu metod, bir form alanının tüm validasyon kurallarını tek seferde ayarlar. Mevcut kuralları tamamen değiştirir. Rules özelliğini verilen slice ile günceller ve method chaining desteği için *FieldUpdate döndürür. Dinamik validasyon senaryoları için kritik öneme sahiptir.
Kullanım Senaryoları ¶
- **Koşullu Validasyon**: Kullanıcı seçimlerine göre farklı validasyon kuralları uygula - **Dinamik Kural Setleri**: İş kurallarına göre validasyon kurallarını değiştir - **Rol Bazlı Validasyon**: Kullanıcı rolüne göre farklı validasyon seviyeleri - **Adım Bazlı Validasyon**: Form adımlarına göre farklı kurallar uygula - **Toplu Kural Güncelleme**: Birden fazla kuralı aynı anda güncelle
Parametreler ¶
- `rules`: ValidationRule slice'ı - Uygulanacak tüm validasyon kuralları
Dönüş Değeri ¶
`*FieldUpdate`: Method chaining için güncellenmiş FieldUpdate pointer'ı
Kullanım Örneği ¶
```go // Basit kullanım
rules := []ValidationRule{
{Type: "required", Message: "Bu alan zorunludur"},
{Type: "min", Value: 3, Message: "En az 3 karakter olmalıdır"},
{Type: "max", Value: 50, Message: "En fazla 50 karakter olabilir"},
}
update := NewFieldUpdate().SetRules(rules)
// Koşullu validasyon - Kullanıcı tipine göre
userTypeField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
userType := formData["user_type"].(string)
var rules []ValidationRule
if userType == "corporate" {
// Kurumsal kullanıcılar için sıkı kurallar
rules = []ValidationRule{
{Type: "required", Message: "Vergi numarası zorunludur"},
{Type: "length", Value: 10, Message: "Vergi numarası 10 haneli olmalıdır"},
{Type: "numeric", Message: "Sadece rakam içermelidir"},
{Type: "tax_number", Message: "Geçerli bir vergi numarası değil"},
}
} else {
// Bireysel kullanıcılar için esnek kurallar
rules = []ValidationRule{
{Type: "length", Value: 11, Message: "TC Kimlik No 11 haneli olmalıdır"},
{Type: "numeric", Message: "Sadece rakam içermelidir"},
}
}
return NewFieldUpdate().
SetRules(rules).
MakeRequired().
SetHelpText(fmt.Sprintf("%s için kimlik bilgisi", userType))
})
// Adım bazlı validasyon
stepField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
step := formData["current_step"].(int)
var emailRules []ValidationRule
if step == 1 {
// İlk adımda basit validasyon
emailRules = []ValidationRule{
{Type: "required", Message: "E-posta zorunludur"},
{Type: "email", Message: "Geçerli bir e-posta adresi girin"},
}
} else if step == 2 {
// İkinci adımda detaylı validasyon
emailRules = []ValidationRule{
{Type: "required", Message: "E-posta zorunludur"},
{Type: "email", Message: "Geçerli bir e-posta adresi girin"},
{Type: "unique", Table: "users", Column: "email", Message: "Bu e-posta zaten kullanılıyor"},
{Type: "domain_whitelist", Value: []string{"company.com", "partner.com"}, Message: "Sadece şirket e-postaları kabul edilir"},
}
}
return NewFieldUpdate().SetRules(emailRules)
})
// Rol bazlı validasyon userRole := ctx.Locals("user_role").(string) var priceRules []ValidationRule
if userRole == "admin" {
// Admin için sınırsız
priceRules = []ValidationRule{
{Type: "required", Message: "Fiyat zorunludur"},
{Type: "numeric", Message: "Geçerli bir sayı girin"},
{Type: "min", Value: 0, Message: "Fiyat negatif olamaz"},
}
} else if userRole == "manager" {
// Manager için sınırlı
priceRules = []ValidationRule{
{Type: "required", Message: "Fiyat zorunludur"},
{Type: "numeric", Message: "Geçerli bir sayı girin"},
{Type: "min", Value: 0, Message: "Fiyat negatif olamaz"},
{Type: "max", Value: 10000, Message: "Maksimum 10.000 TL girebilirsiniz"},
}
} else {
// Normal kullanıcı için çok sınırlı
priceRules = []ValidationRule{
{Type: "required", Message: "Fiyat zorunludur"},
{Type: "numeric", Message: "Geçerli bir sayı girin"},
{Type: "min", Value: 0, Message: "Fiyat negatif olamaz"},
{Type: "max", Value: 1000, Message: "Maksimum 1.000 TL girebilirsiniz"},
}
}
return NewFieldUpdate().
SetRules(priceRules).
SetHelpText(fmt.Sprintf("Rol: %s - Fiyat limitleri uygulanıyor", userRole))
// Ürün tipine göre validasyon
productTypeField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
productType := formData["product_type"].(string)
var descriptionRules []ValidationRule
if productType == "premium" {
// Premium ürünler için detaylı açıklama zorunlu
descriptionRules = []ValidationRule{
{Type: "required", Message: "Premium ürünler için açıklama zorunludur"},
{Type: "min", Value: 100, Message: "En az 100 karakter olmalıdır"},
{Type: "max", Value: 5000, Message: "En fazla 5000 karakter olabilir"},
{Type: "rich_text", Message: "Zengin metin formatı gereklidir"},
}
} else {
// Standart ürünler için basit açıklama
descriptionRules = []ValidationRule{
{Type: "min", Value: 20, Message: "En az 20 karakter olmalıdır"},
{Type: "max", Value: 500, Message: "En fazla 500 karakter olabilir"},
}
}
return NewFieldUpdate().SetRules(descriptionRules)
})
// Boş kural seti (tüm validasyonları kaldır) update := NewFieldUpdate().SetRules([]ValidationRule{}) ```
Önemli Notlar ¶
- **Mevcut Kuralları Değiştirir**: SetRules() mevcut tüm kuralları siler ve yenileriyle değiştirir - **Boş Slice**: Boş slice göndermek tüm validasyon kurallarını kaldırır - **Kural Sırası**: Kurallar verilen sırada uygulanır - **Performans**: Çok fazla kural performansı etkileyebilir - **Sunucu Tarafı**: Client-side validasyon yeterli değildir, sunucu tarafında da validasyon yapın
ValidationRule Yapısı ¶
```go
type ValidationRule struct {
Type string // Kural tipi: "required", "min", "max", "email", "numeric" vb.
Value interface{} // Kural değeri (min/max için sayı, pattern için regex vb.)
Message string // Hata mesajı
Table string // Unique kontrolü için tablo adı
Column string // Unique kontrolü için kolon adı
}
```
Yaygın Kural Tipleri ¶
- `required`: Alan zorunludur - `min`: Minimum değer/uzunluk - `max`: Maximum değer/uzunluk - `email`: E-posta formatı - `numeric`: Sayısal değer - `alpha`: Sadece harf - `alphanumeric`: Harf ve rakam - `url`: URL formatı - `regex`: Regex pattern - `unique`: Veritabanında benzersiz - `length`: Sabit uzunluk - `in`: Belirli değerlerden biri - `not_in`: Belirli değerlerden hiçbiri
Best Practices ¶
- Kullanıcı dostu hata mesajları yazın - Gereksiz kurallardan kaçının (performans) - Kuralları mantıksal sıraya göre düzenleyin (required önce, detaylı kurallar sonra) - Sunucu tarafında da aynı kuralları uygulayın - Karmaşık kurallar için custom validator yazın - Hata mesajlarında örnek verin
Avantajlar ¶
- Dinamik ve esnek validasyon sağlar - İş kurallarını kolayca uygular - Kullanıcı deneyimini iyileştirir - Veri bütünlüğünü sağlar - Toplu kural güncellemesi yapar
Dezavantajlar ¶
- Mevcut kuralları tamamen değiştirir (dikkatli kullanılmalı) - Çok fazla kural performansı etkileyebilir - Karmaşık kural setleri yönetimi zorlaştırabilir
SetRules vs AddRule Karşılaştırması ¶
| Özellik | SetRules | AddRule | |---------|----------|---------| | Mevcut Kurallar | Siler ve değiştirir | Korur ve ekler | | Kullanım | Toplu güncelleme | Tekli ekleme | | Performans | Tek seferde | Her çağrıda | | Esneklik | Düşük | Yüksek | | Kullanım Amacı | Tüm kuralları değiştir | Kural ekle |
func (*FieldUpdate) SetValue ¶
func (u *FieldUpdate) SetValue(value interface{}) *FieldUpdate
SetValue, alanın değerini programatik olarak ayarlar.
Genel Bakış ¶
Bu metod, bir form alanının değerini programatik olarak ayarlar. Value özelliğini verilen değer ile günceller ve method chaining desteği için *FieldUpdate döndürür. Bu özellik, hesaplanan değerler, otomatik doldurma ve değer senkronizasyonu için kullanılır.
Kullanım Senaryoları ¶
- **Hesaplanan Değerler**: Diğer alanların değerlerine göre otomatik hesaplama yap - **Otomatik Doldurma**: Kullanıcı seçimlerine göre alanları otomatik doldur - **Değer Senkronizasyonu**: Bir alanın değerini diğer alanlara kopyala - **Varsayılan Değerler**: Koşullara göre varsayılan değerler ata - **Değer Temizleme**: Belirli koşullarda alanları temizle (nil) - **Format Dönüşümü**: Bir formattan diğerine dönüştür
Parametreler ¶
- `value`: Atanacak değer (interface{} - herhangi bir tip olabilir)
- string, int, float64, bool, nil, map, slice vb.
Dönüş Değeri ¶
`*FieldUpdate`: Method chaining için güncellenmiş FieldUpdate pointer'ı
Kullanım Örneği ¶
```go // Basit kullanım update := NewFieldUpdate().SetValue("Yeni değer")
// Değer temizleme update := NewFieldUpdate().SetValue(nil)
// Hesaplanan değer - Toplam hesaplama
quantityField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
quantity := formData["quantity"].(float64)
price := formData["price"].(float64)
total := quantity * price
// Toplam alanını güncelle
return NewFieldUpdate().
SetValue(total).
MakeReadOnly().
SetHelpText(fmt.Sprintf("Toplam: %.2f TL", total))
})
// Otomatik doldurma - Şehir seçimine göre posta kodu
cityField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
city := formData["city"].(string)
// Şehir kodlarını map'ten al
cityCodes := map[string]string{
"istanbul": "34",
"ankara": "06",
"izmir": "35",
}
postalCode := cityCodes[city]
return NewFieldUpdate().
SetValue(postalCode).
SetHelpText(fmt.Sprintf("%s için posta kodu: %s", city, postalCode))
})
// Değer senkronizasyonu - E-posta'yı kullanıcı adına kopyala
emailField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
email := formData["email"].(string)
autoFillUsername := formData["auto_fill_username"].(bool)
if autoFillUsername {
// E-posta'nın @ öncesi kısmını kullanıcı adı olarak ata
username := strings.Split(email, "@")[0]
return NewFieldUpdate().
SetValue(username).
SetHelpText("E-posta adresinizden otomatik oluşturuldu")
}
return nil
})
// Cascade seçim temizleme
countryField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
// Ülke değiştiğinde şehir seçimini temizle
return NewFieldUpdate().
SetValue(nil).
SetHelpText("Lütfen yeni ülkeye göre şehir seçin")
})
// Format dönüşümü - Telefon numarası formatlama
phoneField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
phone := formData["phone"].(string)
// Sadece rakamları al
digits := regexp.MustCompile(`\D`).ReplaceAllString(phone, "")
// Formatla: (0532) 123 45 67
if len(digits) == 11 {
formatted := fmt.Sprintf("(%s) %s %s %s",
digits[0:4], digits[4:7], digits[7:9], digits[9:11])
return NewFieldUpdate().
SetValue(formatted).
SetHelpText("Telefon numarası formatlandı")
}
return nil
})
// Koşullu varsayılan değer
paymentMethodField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
paymentMethod := formData["payment_method"].(string)
if paymentMethod == "installment" {
// Taksitli ödeme seçildiğinde varsayılan taksit sayısı
return NewFieldUpdate().
SetValue(3).
SetHelpText("Varsayılan: 3 taksit")
}
return NewFieldUpdate().SetValue(nil)
})
// Veritabanından değer çekme
productField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
productID := formData["product_id"].(int)
// Ürün fiyatını veritabanından çek
var product Product
db := ctx.Locals("db").(*gorm.DB)
db.First(&product, productID)
// Fiyat alanını otomatik doldur
return NewFieldUpdate().
SetValue(product.Price).
MakeReadOnly().
SetHelpText(fmt.Sprintf("Ürün fiyatı: %.2f TL", product.Price))
})
// Karmaşık nesne değeri
addressField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
addressData := map[string]interface{}{
"street": "Atatürk Caddesi",
"city": "İstanbul",
"postal_code": "34000",
"country": "TR",
}
return NewFieldUpdate().SetValue(addressData)
})
```
Önemli Notlar ¶
- **Tip Güvenliği**: interface{} kullanıldığı için tip dönüşümlerine dikkat edin - **Nil Değer**: nil göndermek alanı temizler - **Validasyon**: SetValue ile atanan değerler de validasyon kurallarına tabidir - **Kullanıcı Girişi**: Programatik değer ataması kullanıcı girişini ezer - **ReadOnly ile Kullanım**: Hesaplanan değerler için MakeReadOnly() ile birlikte kullanın
Best Practices ¶
- Hesaplanan değerler için MakeReadOnly() kullanın - Tip dönüşümlerinde hata kontrolü yapın - Cascade seçimlerde önceki değeri temizleyin (nil) - Kullanıcıya değerin nereden geldiğini açıklayın (yardım metni) - Veritabanı sorgularında hata kontrolü yapın - Format dönüşümlerinde validasyon yapın
Avantajlar ¶
- Otomatik hesaplama sağlar - Kullanıcı deneyimini iyileştirir - Veri tutarlılığını sağlar - Form doldurma süresini kısaltır - Hata oranını azaltır
Dezavantajlar ¶
- Yanlış kullanımda kullanıcı girişini ezebilir - Tip güvenliği yoktur (interface{}) - Karmaşık hesaplamalarda performans sorunları olabilir
Güvenlik Notları ¶
- Kullanıcı girişini doğrudan kullanmadan önce sanitize edin - Veritabanı sorgularında SQL injection'a dikkat edin - Hassas bilgileri (şifre, kredi kartı) SetValue ile atamayın - Sunucu tarafında da aynı hesaplamaları yapın (güvenlik)
func (*FieldUpdate) Show ¶
func (u *FieldUpdate) Show() *FieldUpdate
Show, alanı görünür hale getirir.
Genel Bakış ¶
Bu metod, bir form alanının kullanıcı arayüzünde görünür olmasını sağlar. Visible özelliğini true olarak ayarlar ve method chaining desteği için *FieldUpdate döndürür.
Kullanım Senaryoları ¶
- Koşullu alan görünürlüğü: Belirli bir değer seçildiğinde ilgili alanları göster - Dinamik form yapısı: Kullanıcı seçimlerine göre form alanlarını göster/gizle - Wizard formlar: Adım adım form akışında ilgili alanları göster - Koşullu validasyon: Görünür olan alanlar için validasyon uygula
Dönüş Değeri ¶
`*FieldUpdate`: Method chaining için güncellenmiş FieldUpdate pointer'ı
Kullanım Örneği ¶
```go // Basit kullanım update := NewFieldUpdate().Show()
// Koşullu görünürlük
if formData["has_company"] == true {
return NewFieldUpdate().Show().MakeRequired()
}
// Çoklu alan kontrolü
countryField.OnChange(func(field *Schema, formData map[string]interface{}, ctx *fiber.Ctx) *FieldUpdate {
country := formData["country"]
if country == "TR" {
// Türkiye seçildiğinde TC Kimlik No alanını göster
return NewFieldUpdate().Show().MakeRequired().SetHelpText("11 haneli TC Kimlik No")
}
return NewFieldUpdate().Hide()
})
// Method chaining ile birlikte kullanım update := NewFieldUpdate().
Show().
MakeRequired().
Enable().
SetHelpText("Bu alan artık görünür ve zorunlu")
```
Önemli Notlar ¶
- Show() çağrıldığında alan görünür olur ancak disabled durumu değişmez - Görünür olan alanlar için validasyon kuralları uygulanır - Hide() ile gizlenen alanlar için validasyon atlanır - Method chaining desteklenir, zincirleme çağrılar yapılabilir
Best Practices ¶
- Show() ile birlikte MakeRequired() veya MakeOptional() kullanarak validasyon durumunu belirtin - Görünür hale getirilen alanlara uygun yardım metni ekleyin - Koşullu görünürlükte her iki durumu da (Show/Hide) ele alın
type Filterable ¶
type Filterable struct {
// contains filtered or unexported fields
}
Filterable, alanların filtrelenebilir olmasını sağlayan bir mixin'dir.
Filtrelenebilir davranış, filtre seçenekleri ve özel filtre callback'leri için yapılandırma sağlar. Bu callback'ler veritabanı sorgusunu değiştirebilir.
Kullanım ¶
type SelectField struct {
fields.Base
fields.Filterable
}
field := &SelectField{}
field.SetFilterable(true)
field.SetFilterOptions(map[string]string{
"active": "Aktif",
"inactive": "İnaktif",
})
field.SetFilterCallback(func(db *gorm.DB, value any) *gorm.DB {
return db.Where("status = ?", value)
})
Daha fazla örnek için docs/Fields.md dosyasına bakın.
func (*Filterable) GetFilterCallback ¶
GetFilterCallback, filtre callback fonksiyonunu döndürür. Hiçbir callback ayarlanmamışsa nil döndürür.
Döndürür:
- Filtre callback fonksiyonu veya ayarlanmamışsa nil
func (*Filterable) GetFilterOptions ¶
func (f *Filterable) GetFilterOptions() map[string]string
GetFilterOptions, filtre seçeneklerini döndürür. Hiçbir seçenek yapılandırılmamışsa boş bir map döndürür.
Döndürür:
- Filtre seçenekleri için değer-etiket eşlemesi
func (*Filterable) IsFilterable ¶
func (f *Filterable) IsFilterable() bool
IsFilterable, alanın filtrelenebilir olup olmadığını döndürür.
Döndürür:
- Alan filtrelenebilirse true, değilse false
func (*Filterable) SetFilterCallback ¶
SetFilterCallback, özel bir filtre callback fonksiyonu ayarlar.
Callback, GORM veritabanı örneğini ve filtre değerini alır, ve filtre sorgusu uygulanmış değiştirilmiş bir veritabanı örneği döndürmelidir.
Parametreler:
- cb: Özel filtre mantığı için veritabanı sorgusunu değiştiren fonksiyon
Örnek:
field.SetFilterCallback(func(db *gorm.DB, value any) *gorm.DB {
status, ok := value.(string)
if !ok {
return db
}
return db.Where("status = ?", status)
})
func (*Filterable) SetFilterOptions ¶
func (f *Filterable) SetFilterOptions(options map[string]string)
SetFilterOptions, kullanılabilir filtre seçeneklerini ayarlar.
Seçenekler, kullanıcıların önceden tanımlanmış değerlere göre filtreleme yapmasına izin veren bir açılır liste veya onay kutusu listesi olarak UI'da gösterilir.
Parametreler:
- options: Filtre seçenekleri için değer-etiket eşlemesi
Örnek:
field.SetFilterOptions(map[string]string{
"draft": "Taslak",
"published": "Yayınlandı",
"archived": "Arşivlendi",
})
func (*Filterable) SetFilterable ¶
func (f *Filterable) SetFilterable(filterable bool)
SetFilterable, alanın filtrelenebilir olup olmadığını ayarlar.
Parametreler:
- filterable: Filtrelemeyi etkinleştirmek için true, devre dışı bırakmak için false
Örnek:
field.SetFilterable(true)
type GormConfig ¶
type GormConfig struct {
// Anahtar Yapılandırması
PrimaryKey bool `json:"-"` // Birincil anahtar mı?
AutoIncrement bool `json:"-"` // Otomatik artış mı?
IDType string `json:"-"` // ID tipi: "uuid" (shared/uuid), "snowflake" (github.com/bwmarrin/snowflake), "ulid" (github.com/oklog/ulid)
// Sütun Yapılandırması
Column string `json:"-"` // Özel sütun adı (varsayılan: Key'den türetilir)
Type string `json:"-"` // SQL tipi (örn: "varchar(255)", "text", "decimal(10,2)")
Size int `json:"-"` // Sütun boyutu (VARCHAR için)
// Sayısal Hassasiyet
Precision int `json:"-"` // Ondalık hassasiyet (DECIMAL tipi için)
Scale int `json:"-"` // Ondalık ölçek (DECIMAL tipi için)
// İndeks Yapılandırması
Index bool `json:"-"` // Normal indeks oluştur
UniqueIndex bool `json:"-"` // Benzersiz indeks oluştur
FullTextIndex bool `json:"-"` // Fulltext indeks oluştur
IndexName string `json:"-"` // Özel indeks adı
// Varsayılan Değer
Default interface{} `json:"-"` // Varsayılan değer
// Kısıtlamalar
NotNull bool `json:"-"` // NOT NULL kısıtlaması
Comment string `json:"-"` // Sütun yorumu
SoftDelete bool `json:"-"` // Soft delete desteği (DeletedAt alanı)
// İlişki Yapılandırması (Foreign Key)
ForeignKey string `json:"-"` // Foreign key alanı (örn: "AuthorID")
References string `json:"-"` // Referans tablo.alan (örn: "users.id")
OnDelete string `json:"-"` // ON DELETE davranışı (CASCADE, SET NULL, vb.)
OnUpdate string `json:"-"` // ON UPDATE davranışı
ManyToManyTable string `json:"-"` // Many-to-many ara tablo adı
JoinForeignKey string `json:"-"` // Join tablosundaki foreign key
JoinReferences string `json:"-"` // Join tablosundaki referans
}
GormConfig, alan için GORM veritabanı yapılandırmasını tanımlar. Bu yapı, alan tanımlarından otomatik migration ve model oluşturma için kullanılır.
func NewGormConfig ¶
func NewGormConfig() *GormConfig
NewGormConfig, varsayılan değerlerle yeni bir GormConfig oluşturur.
func (*GormConfig) ToGormTag ¶
func (g *GormConfig) ToGormTag() string
ToGormTag, GormConfig'i GORM struct tag string'ine dönüştürür.
func (*GormConfig) WithAutoIncrement ¶
func (g *GormConfig) WithAutoIncrement() *GormConfig
WithAutoIncrement, otomatik artış olarak işaretler.
func (*GormConfig) WithColumn ¶
func (g *GormConfig) WithColumn(name string) *GormConfig
WithColumn, özel sütun adı belirler.
func (*GormConfig) WithComment ¶
func (g *GormConfig) WithComment(comment string) *GormConfig
WithComment, sütun yorumu ekler.
func (*GormConfig) WithDefault ¶
func (g *GormConfig) WithDefault(value interface{}) *GormConfig
WithDefault, varsayılan değer belirler.
func (*GormConfig) WithForeignKey ¶
func (g *GormConfig) WithForeignKey(fk, references string) *GormConfig
WithForeignKey, foreign key ilişkisi tanımlar.
func (*GormConfig) WithFullTextIndex ¶
func (g *GormConfig) WithFullTextIndex(name ...string) *GormConfig
WithFullTextIndex, fulltext indeks oluşturur.
func (*GormConfig) WithIDType ¶
func (g *GormConfig) WithIDType(idType string) *GormConfig
WithIDType, ID tipini belirler (uuid, snowflake, ulid).
func (*GormConfig) WithIndex ¶
func (g *GormConfig) WithIndex(name ...string) *GormConfig
WithIndex, normal indeks oluşturur.
func (*GormConfig) WithManyToMany ¶
func (g *GormConfig) WithManyToMany(tableName string) *GormConfig
WithManyToMany, many-to-many ilişki için ara tablo tanımlar.
func (*GormConfig) WithNotNull ¶
func (g *GormConfig) WithNotNull() *GormConfig
WithNotNull, NOT NULL kısıtlaması ekler.
func (*GormConfig) WithOnDelete ¶
func (g *GormConfig) WithOnDelete(action string) *GormConfig
WithOnDelete, ON DELETE davranışını belirler.
func (*GormConfig) WithOnUpdate ¶
func (g *GormConfig) WithOnUpdate(action string) *GormConfig
WithOnUpdate, ON UPDATE davranışını belirler.
func (*GormConfig) WithPrecision ¶
func (g *GormConfig) WithPrecision(precision, scale int) *GormConfig
WithPrecision, ondalık hassasiyeti belirler.
func (*GormConfig) WithPrimaryKey ¶
func (g *GormConfig) WithPrimaryKey() *GormConfig
WithPrimaryKey, birincil anahtar olarak işaretler.
func (*GormConfig) WithSize ¶
func (g *GormConfig) WithSize(size int) *GormConfig
WithSize, sütun boyutunu belirler.
func (*GormConfig) WithSnowflake ¶
func (g *GormConfig) WithSnowflake() *GormConfig
WithSnowflake, Snowflake tipinde ID kullanır.
func (*GormConfig) WithSoftDelete ¶
func (g *GormConfig) WithSoftDelete() *GormConfig
WithSoftDelete, soft delete desteği ekler.
func (*GormConfig) WithType ¶
func (g *GormConfig) WithType(sqlType string) *GormConfig
WithType, SQL tipini belirler.
func (*GormConfig) WithULID ¶
func (g *GormConfig) WithULID() *GormConfig
WithULID, ULID tipinde ID kullanır.
func (*GormConfig) WithUUID ¶
func (g *GormConfig) WithUUID() *GormConfig
WithUUID, UUID tipinde ID kullanır.
func (*GormConfig) WithUniqueIndex ¶
func (g *GormConfig) WithUniqueIndex(name ...string) *GormConfig
WithUniqueIndex, benzersiz indeks oluşturur.
type HasManyField ¶
type HasManyField struct {
Schema
RelatedResourceSlug string
RelatedResource interface{} // resource.Resource interface (interface{} to avoid circular import)
ForeignKeyColumn string
OwnerKeyColumn string
QueryCallback func(query interface{}) interface{}
LoadingStrategy LoadingStrategy
GormRelationConfig *RelationshipGormConfig
FullDataMode bool // true: raw data + title, false (default): minimal format (id + title)
}
HasManyField, one-to-many ilişkiyi temsil eder (örn. Author -> Posts).
HasMany ilişkisi, bir kaydın birden fazla ilişkili kayda sahip olduğunu belirtir. Bu, veritabanında ilişkili tabloda foreign key ile temsil edilir.
Kullanım Senaryoları ¶
- **Author -> Posts**: Bir yazar birden fazla yazıya sahiptir - **Category -> Products**: Bir kategori birden fazla ürüne sahiptir - **User -> Comments**: Bir kullanıcı birden fazla yoruma sahiptir
Özellikler ¶
- **Tip Güvenliği**: Resource instance veya string slug kullanılabilir - **Foreign Key Özelleştirme**: İlişkili tablodaki foreign key sütunu özelleştirilebilir - **Owner Key Özelleştirme**: Ana tablodaki referans sütunu özelleştirilebilir - **Eager/Lazy Loading**: Yükleme stratejisi seçimi - **GORM Yapılandırması**: Foreign key ve references özelleştirme
Kullanım Örneği ¶
// String slug ile
field := fields.HasMany("Posts", "posts", "posts").
ForeignKey("author_id").
WithEagerLoad()
// Resource instance ile (tip güvenli)
field := fields.HasMany("Posts", "posts", blog.NewPostResource()).
ForeignKey("author_id").
WithEagerLoad()
Daha fazla bilgi için docs/Relationships.md dosyasına bakın.
func HasMany ¶
func HasMany(name, key string, relatedResource interface{}) *HasManyField
HasMany, yeni bir HasMany ilişki alanı oluşturur.
Bu fonksiyon, hem string slug hem de resource instance kabul eder. Resource instance kullanımı tip güvenliği sağlar ve refactoring'i kolaylaştırır.
Parametreler ¶
- **name**: Alanın görünen adı (örn. "Posts", "Yazılar") - **key**: İlişki key'i (örn. "posts") - **relatedResource**: İlgili resource (string slug veya resource instance)
String Slug Kullanımı ¶
field := fields.HasMany("Posts", "posts", "posts")
**Avantajlar:** - Basit ve hızlı - Circular import sorunu yok
**Dezavantajlar:** - Tip güvenliği yok - Refactoring zor - IDE desteği sınırlı
Resource Instance Kullanımı (Önerilen) ¶
field := fields.HasMany("Posts", "posts", blog.NewPostResource())
**Avantajlar:** - ✅ Tip güvenliği (derleme zamanı kontrolü) - ✅ Refactoring desteği (resource adı değişirse otomatik güncellenir) - ✅ IDE desteği (autocomplete, go-to-definition) - ✅ Tablo adı otomatik alınır (resource.Slug())
**Dezavantajlar:** - Circular import'a dikkat edilmeli
Varsayılan Değerler ¶
- **ForeignKeyColumn**: slug + "_id" (örn. "posts_id") - **OwnerKeyColumn**: "id" (ana tablonun primary key'i) - **LoadingStrategy**: EAGER_LOADING (N+1 sorgu problemini önler)
Döndürür:
- Yapılandırılmış HasManyField pointer'ı
Daha fazla bilgi için docs/Relationships.md ve .docs/RESOURCE_BASED_RELATIONSHIPS.md dosyalarına bakın.
func (*HasManyField) AutoOptions ¶
func (h *HasManyField) AutoOptions(displayField string) *HasManyField
AutoOptions, ilişkili tablodan otomatik options oluşturmayı etkinleştirir.
Bu metod, HasMany ilişkisinde ilişkili kayıtların otomatik olarak yüklenmesini ve frontend'de multi-select combobox'ta gösterilmesini sağlar.
Parametreler ¶
- **displayField**: Option label'ı için kullanılacak sütun adı (örn. "title", "name")
Kullanım Örneği ¶
// Author resource'unda Posts ilişkisi
field := fields.HasMany("Posts", "posts", "posts").
AutoOptions("title"). // Post'ların "title" sütunu label olarak kullanılır
ForeignKey("author_id").
WithEagerLoad()
Backend Response Formatı ¶
AutoOptions etkinleştirildiğinde, backend response'unda options otomatik olarak eklenir:
{
"posts": {
"key": "posts",
"type": "relationship",
"view": "has-many-field",
"data": [1, 2, 3],
"props": {
"related_resource": "posts",
"options": {
"1": "First Post",
"2": "Second Post",
"3": "Third Post"
}
}
}
}
Frontend Rendering ¶
Frontend'de HasManyField componenti otomatik olarak: - Pre-loaded options'ları multi-select combobox'ta gösterir - Search fonksiyonu ile filtreleme yapar - Seçili değerleri chips olarak gösterir - Kullanıcı yeni kayıtlar seçebilir veya mevcut seçimleri kaldırabilir
Önemli Notlar ¶
- displayField sütunu, ilişkili tabloda mevcut olmalıdır - Büyük veri setleri için (10,000+ kayıt) performans sorunları olabilir - Best practice: AutoOptions sadece küçük-orta veri setleri için kullanın - Null değerler için otomatik fallback kontrolü yapılır
Döndürür:
- HasManyField pointer'ı (method chaining için)
func (*HasManyField) Count ¶
func (h *HasManyField) Count() int64
Count returns the count of related resources
func (*HasManyField) Extract ¶
func (h *HasManyField) Extract(resource interface{})
Extract, HasMany ilişkisi için özel veri çıkarma metodudur.
Bu metod, Schema'nın genel Extract metodunu override eder ve HasMany ilişkisi için özel işlem yapar. İlişkili kayıtları JSON tag'lere göre serialize eder.
İşleyiş ¶
- Schema'nın Extract metodunu çağırır (mevcut davranışı korumak için)
- Eğer Data nil ise, boş array olarak ayarlar
- Eğer Data bir slice ise: a. Her kayıt için JSON marshaling yapar (JSON tag'ler otomatik kullanılır) b. JSON'dan map[string]interface{}'e unmarshal eder c. Bu map'leri data array'ine ekler
JSON Tag Kullanımı ¶
Model'de tanımlı JSON tag'ler otomatik olarak kullanılır:
type Address struct {
ID uint `json:"id"`
OrganizationID uint `json:"organization_id"`
Name string `json:"name"`
}
Sonuç: {"id": 1, "organization_id": 16, "name": "Adres"}
Parametreler ¶
- resource: Veri çıkarılacak kaynak (struct veya map)
Kullanım Örneği ¶
// Organization model'inde Addresses field'ı var
type Organization struct {
ID uint
Name string
Addresses []Address
}
// HasMany field Extract çağrıldığında
field := fields.HasMany("Addresses", "addresses", "addresses")
field.Extract(&organization)
// field.Data artık [{"id": 1, "organization_id": 16, ...}] gibi JSON tag'lere göre serialize edilmiş kayıtlar içerir
func (*HasManyField) ForeignKey ¶
func (h *HasManyField) ForeignKey(key string) *HasManyField
ForeignKey, foreign key sütun adını ayarlar.
Bu metod, ilişkili tablodaki foreign key sütununun adını özelleştirir. Varsayılan olarak slug + "_id" kullanılır.
Parametreler ¶
- **key**: Foreign key sütun adı (örn. "author_id", "user_id", "category_id")
Kullanım Örneği ¶
field := fields.HasMany("Posts", "posts", "posts").
ForeignKey("author_id")
// Posts tablosunda "author_id" sütunu foreign key olarak kullanılır
Önemli Notlar ¶
- Foreign key sütunu, ilişkili tabloda mevcut olmalıdır - Genellikle "parent_table_id" formatında olur (örn. "author_id", "category_id") - GORM tarafından otomatik olarak ilişki kurulumu için kullanılır
Döndürür:
- HasManyField pointer'ı (method chaining için)
func (*HasManyField) GetDisplayKey ¶
func (h *HasManyField) GetDisplayKey() string
GetDisplayKey returns the display key (not used for HasMany)
func (*HasManyField) GetForeignKeyColumn ¶
func (h *HasManyField) GetForeignKeyColumn() string
GetForeignKeyColumn, foreign key sütun adını döndürür.
Bu metod, HasMany ilişkisinde kullanılan foreign key sütununun adını döndürür. Foreign key, ilişkili tablodaki referans sütunudur.
Dönüş Değeri ¶
- Foreign key sütun adı (örn. "author_id", "user_id", "category_id")
Kullanım Örneği ¶
field := fields.HasMany("Posts", "posts", "posts").ForeignKey("author_id")
foreignKey := field.GetForeignKeyColumn() // "author_id"
Döndürür:
- Foreign key sütun adı
func (*HasManyField) GetLoadingStrategy ¶
func (h *HasManyField) GetLoadingStrategy() LoadingStrategy
GetLoadingStrategy returns the loading strategy
func (*HasManyField) GetOwnerKeyColumn ¶
func (h *HasManyField) GetOwnerKeyColumn() string
GetOwnerKeyColumn, owner key sütun adını döndürür.
Bu metod, HasMany ilişkisinde kullanılan owner key sütununun adını döndürür. Owner key, ana tablodaki referans sütunudur (genellikle primary key).
Dönüş Değeri ¶
- Owner key sütun adı (örn. "id", "uuid")
Kullanım Örneği ¶
field := fields.HasMany("Posts", "posts", "posts").OwnerKey("id")
ownerKey := field.GetOwnerKeyColumn() // "id"
Döndürür:
- Owner key sütun adı
func (*HasManyField) GetQueryCallback ¶
func (h *HasManyField) GetQueryCallback() func(interface{}) interface{}
GetQueryCallback returns the query callback
func (*HasManyField) GetRelatedResource ¶
func (h *HasManyField) GetRelatedResource() interface{}
GetRelatedResource, ilişkili resource instance'ını döndürür.
Bu metod, RelatedResource'a erişim sağlar.
Dönüş Değeri ¶
- interface{}: Resource instance'ı (resource.Resource interface) - nil: RelatedResource set edilmemişse
Kullanım Örneği ¶
// Extract metodunda
if h.GetRelatedResource() == nil {
// RelatedResource set edilmemiş, minimal format kullan
return
}
Döndürür:
- Resource instance'ı veya nil
func (*HasManyField) GetRelatedResourceSlug ¶
func (h *HasManyField) GetRelatedResourceSlug() string
GetRelatedResourceSlug, ilişkili resource'un slug'ını döndürür.
Bu metod, RelatedResourceSlug'a erişim sağlar. Genellikle field_handler.go'da resource registry'den resource instance'ı almak için kullanılır.
Dönüş Değeri ¶
- string: Resource slug'ı (örn. "users", "posts", "addresses")
Kullanım Örneği ¶
// field_handler.go'da
if relField, ok := element.(*fields.HasManyField); ok {
slug := relField.GetRelatedResourceSlug()
relatedResource := resource.Get(slug)
relField.SetRelatedResource(relatedResource)
}
Döndürür:
- Resource slug'ı
func (*HasManyField) GetRelatedTableName ¶
func (h *HasManyField) GetRelatedTableName() string
GetRelatedTableName, ilişkili tablo adını döndürür.
Bu metod, HasMany ilişkisinde kullanılan ilişkili tablonun adını döndürür. Raw SQL sorguları için kullanılır.
Dönüş Değeri ¶
- İlişkili tablo adı (örn. "posts", "comments", "orders")
Kullanım Örneği ¶
field := fields.HasMany("Posts", "posts", "posts")
tableName := field.GetRelatedTableName() // "posts"
Döndürür:
- İlişkili tablo adı
func (*HasManyField) GetRelationshipName ¶
func (h *HasManyField) GetRelationshipName() string
GetRelationshipName returns the relationship name
func (*HasManyField) GetRelationshipType ¶
func (h *HasManyField) GetRelationshipType() string
GetRelationshipType returns the relationship type
func (*HasManyField) GetSearchableColumns ¶
func (h *HasManyField) GetSearchableColumns() []string
GetSearchableColumns returns the searchable columns (not used for HasMany)
func (*HasManyField) GetTypes ¶
func (h *HasManyField) GetTypes() map[string]string
GetTypes returns the type mappings (not used for HasMany)
func (*HasManyField) IsRequired ¶
func (h *HasManyField) IsRequired() bool
IsRequired returns whether the field is required
func (*HasManyField) Label ¶
func (h *HasManyField) Label(label string) Element
Label sets the field label while preserving HasMany concrete type in fluent chains.
func (*HasManyField) OwnerKey ¶
func (h *HasManyField) OwnerKey(key string) *HasManyField
OwnerKey, owner key sütun adını ayarlar.
Bu metod, ana tablodaki referans sütununun adını özelleştirir. Varsayılan olarak "id" (primary key) kullanılır.
Parametreler ¶
- **key**: Owner key sütun adı (örn. "id", "uuid", "author_id")
Kullanım Örneği ¶
field := fields.HasMany("Posts", "posts", "posts").
ForeignKey("author_id").
OwnerKey("id")
// Authors tablosundaki "id" sütunu ile Posts tablosundaki "author_id" sütunu eşleştirilir
Önemli Notlar ¶
- Owner key sütunu, ana tabloda mevcut olmalıdır - Genellikle primary key kullanılır ("id") - Özel durumlar için farklı sütunlar kullanılabilir (örn. "uuid")
Döndürür:
- HasManyField pointer'ı (method chaining için)
func (*HasManyField) Placeholder ¶
func (h *HasManyField) Placeholder(placeholder string) Element
Placeholder sets the field placeholder while preserving HasMany concrete type in fluent chains.
func (*HasManyField) Query ¶
func (h *HasManyField) Query(fn func(interface{}) interface{}) *HasManyField
Query sets the query callback for customizing relationship query
func (*HasManyField) ResolveRelationship ¶
func (h *HasManyField) ResolveRelationship(item interface{}) (interface{}, error)
ResolveRelationship resolves the relationship by loading all related resources
func (*HasManyField) Searchable ¶
func (h *HasManyField) Searchable() Element
Searchable marks the element as searchable (implements Element interface)
func (*HasManyField) SetRelatedResource ¶
func (h *HasManyField) SetRelatedResource(res interface{}) *HasManyField
SetRelatedResource, ilişkili resource instance'ını set eder.
Bu metod, RelatedResource'u runtime'da set etmek için kullanılır. Genellikle field_handler.go'da Extract çağrılmadan önce kullanılır.
Kullanım Senaryoları ¶
- Circular dependency önlemek için string slug kullanıldığında - Runtime'da resource registry'den resource instance'ı alındığında - Field handler'da Extract öncesi RelatedResource'u set etmek
Parametreler ¶
- res: Resource instance'ı (resource.Resource interface)
Kullanım Örneği ¶
// field_handler.go'da Extract öncesi
if relField, ok := element.(*fields.HasManyField); ok {
if relField.RelatedResource == nil {
relatedResource := resource.Get(relField.RelatedResourceSlug)
relField.SetRelatedResource(relatedResource)
}
}
element.Extract(item)
Döndürür:
- HasManyField pointer'ı (method chaining için)
func (*HasManyField) ValidateRelationship ¶
func (h *HasManyField) ValidateRelationship(value interface{}) error
ValidateRelationship validates the relationship
func (*HasManyField) WithEagerLoad ¶
func (h *HasManyField) WithEagerLoad() *HasManyField
WithEagerLoad sets the loading strategy to eager loading
func (*HasManyField) WithFullData ¶
func (h *HasManyField) WithFullData() *HasManyField
WithFullData, ilişkili kayıtların tam verilerini (raw data + title) döndürmesini sağlar.
Bu metod, Extract metodunun davranışını değiştirir: - Varsayılan (FullDataMode=false): Minimal format (sadece id + title) - WithFullData() çağrıldığında (FullDataMode=true): Full format (tüm raw data + title)
Kullanım Senaryoları ¶
- Frontend'de ilişkili kayıtların detaylı bilgilerini göstermek - Relationship field'larında tüm veriyi kullanmak - Custom rendering için ek field'lara ihtiyaç duymak
Kullanım Örneği ¶
// Minimal format (varsayılan): {"id": 1, "title": "Adres 1"}
fields.HasMany("Addresses", "addresses", "addresses")
// Full format: {"ID": 1, "Name": "Adres 1", "City": "İstanbul", ..., "title": "Adres 1"}
fields.HasMany("Addresses", "addresses", "addresses").
WithFullData()
Döndürür:
- HasManyField pointer'ı (method chaining için)
func (*HasManyField) WithLazyLoad ¶
func (h *HasManyField) WithLazyLoad() *HasManyField
WithLazyLoad sets the loading strategy to lazy loading
type HasOneField ¶
type HasOneField struct {
Schema
RelatedResourceSlug string
RelatedResource interface{} // resource.Resource interface (interface{} to avoid circular import)
ForeignKeyColumn string
OwnerKeyColumn string
QueryCallback func(query interface{}) interface{}
LoadingStrategy LoadingStrategy
GormRelationConfig *RelationshipGormConfig
// contains filtered or unexported fields
}
HasOneField, one-to-one ilişkiyi temsil eder (örn. User -> Profile).
HasOne ilişkisi, bir kaydın tek bir ilişkili kayda sahip olduğunu belirtir. Bu, veritabanında ilişkili tabloda foreign key ile temsil edilir.
Kullanım Senaryoları ¶
- **User -> Profile**: Bir kullanıcının bir profili vardır - **Country -> Capital**: Bir ülkenin bir başkenti vardır - **Order -> Invoice**: Bir siparişin bir faturası vardır
Özellikler ¶
- **Tip Güvenliği**: Resource instance veya string slug kullanılabilir - **Foreign Key Özelleştirme**: İlişkili tablodaki foreign key sütunu özelleştirilebilir - **Owner Key Özelleştirme**: Ana tablodaki referans sütunu özelleştirilebilir - **Eager/Lazy Loading**: Yükleme stratejisi seçimi - **GORM Yapılandırması**: Foreign key ve references özelleştirme - **Hover Card**: Index ve detail sayfalarında hover card desteği
Kullanım Örneği ¶
// String slug ile
field := fields.HasOne("Profile", "profile", "profiles").
ForeignKey("user_id").
WithEagerLoad()
// Resource instance ile (tip güvenli)
field := fields.HasOne("Profile", "profile", user.NewProfileResource()).
ForeignKey("user_id").
WithEagerLoad()
// Hover card ile
field := fields.HasOne("Profile", "profile", "profiles").
ForeignKey("user_id").
WithHoverCard(fields.NewHoverCardConfig().
WithAvatar("avatar", "").
WithGrid([]fields.HoverCardGridField{
{Key: "bio", Label: "Bio", Type: "text"},
{Key: "location", Label: "Konum", Type: "text", Icon: "map-pin"},
}, "2-column"))
Daha fazla bilgi için docs/Relationships.md dosyasına bakın.
func HasOne ¶
func HasOne(name, key string, relatedResource interface{}) *HasOneField
HasOne, yeni bir HasOne ilişki alanı oluşturur.
Bu fonksiyon, hem string slug hem de resource instance kabul eder. Resource instance kullanımı tip güvenliği sağlar ve refactoring'i kolaylaştırır.
Parametreler ¶
- **name**: Alanın görünen adı (örn. "Profile", "Profil") - **key**: İlişki key'i (örn. "profile") - **relatedResource**: İlgili resource (string slug veya resource instance)
String Slug Kullanımı ¶
field := fields.HasOne("Profile", "profile", "profiles")
Resource Instance Kullanımı (Önerilen) ¶
field := fields.HasOne("Profile", "profile", user.NewProfileResource())
**Avantajlar:** - ✅ Tip güvenliği (derleme zamanı kontrolü) - ✅ Refactoring desteği - ✅ IDE desteği (autocomplete, go-to-definition)
Varsayılan Değerler ¶
- **ForeignKeyColumn**: slug + "_id" (örn. "profiles_id") - **OwnerKeyColumn**: "id" (ana tablonun primary key'i) - **LoadingStrategy**: EAGER_LOADING (N+1 sorgu problemini önler)
Döndürür:
- Yapılandırılmış HasOneField pointer'ı
func (*HasOneField) AutoOptions ¶
func (h *HasOneField) AutoOptions(displayField string) *HasOneField
AutoOptions, ilişkili tablodan otomatik seçenek üretimini etkinleştirir.
Bu method, HasOne ilişkisinde ilişkili kayıtların otomatik olarak seçenek listesi olarak sunulmasını sağlar. Frontend'de dropdown veya select bileşenlerinde kullanılır.
Parametreler ¶
- **displayField**: Seçenek etiketinde gösterilecek sütun adı (örn. "name", "title")
Kullanım Senaryoları ¶
- **Profil Seçimi**: Kullanıcı profili seçerken profil adlarını gösterme - **Başkent Seçimi**: Ülke başkentlerini dropdown'da listeleme - **Fatura Seçimi**: Sipariş için fatura seçerken fatura numaralarını gösterme
Kullanım Örneği ¶
field := fields.HasOne("Profile", "profile", "profiles").
AutoOptions("full_name").
ForeignKey("user_id")
Önemli Notlar ¶
- displayField, ilişkili tabloda mevcut bir sütun olmalıdır - Büyük veri setlerinde performans sorunlarına neden olabilir - Sayfalama ve arama özellikleri ile birlikte kullanılması önerilir
Döndürür:
- Yapılandırılmış HasOneField pointer'ı (method chaining için)
func (*HasOneField) Extract ¶
func (h *HasOneField) Extract(resource interface{})
Extract, resource'dan değeri çıkarır ve işler.
Bu method, HasOne ilişkisinde ilişkili resource'un ID değerini çıkarır. Eğer ilişkili veri bir struct ise, struct'ın ID alanını bulup değer olarak ayarlar. Bu, frontend'e gönderilecek veriyi hazırlar ve sadece ID'yi döndürür.
Çalışma Mantığı ¶
1. Schema.Extract() ile temel extraction yapılır 2. Eğer veri nil ise, işlem sonlandırılır 3. Eğer veri pointer ise, dereference edilir 4. Eğer veri struct ise, ID veya Id alanı aranır 5. Bulunan ID değeri Data alanına atanır
Kullanım Senaryoları ¶
- **API Response**: Frontend'e sadece ilişkili kaydın ID'sini gönderme - **Form Data**: Edit formlarında mevcut ilişkili kaydın ID'sini gösterme - **Serialization**: JSON response'da nested struct yerine ID kullanma - **Data Transformation**: Struct'tan primitive değere dönüşüm
Örnek Veri Dönüşümü ¶
**Giriş (Struct):**
user := User{
ID: 1,
Profile: Profile{
ID: 42,
FullName: "John Doe",
Avatar: "avatar.jpg",
},
}
**Çıkış (ID):**
field.Data = 42 // Sadece Profile ID'si
Desteklenen Veri Tipleri ¶
**Struct:**
Profile{ID: 42, FullName: "John"} → 42
**Pointer to Struct:**
&Profile{ID: 42, FullName: "John"} → 42
**Nil Pointer:**
var profile *Profile = nil → nil
**Primitive (ID zaten var):**
42 → 42 (değişmez)
ID Alan İsimleri ¶
Method, aşağıdaki alan isimlerini sırayla arar: 1. "ID" (büyük harf, Go convention) 2. "Id" (camelCase, alternatif)
Kullanım Örneği ¶
// Resource tanımı
type User struct {
ID uint
Profile Profile
}
type Profile struct {
ID uint
FullName string
}
// Field tanımı
field := fields.HasOne("Profile", "profile", "profiles")
// Extract çağrısı
user := User{
ID: 1,
Profile: Profile{ID: 42, FullName: "John"},
}
field.Extract(user)
// Sonuç
fmt.Println(field.Data) // Output: 42
JSON Serialization ¶
Extract sonrası JSON response:
{
"id": 1,
"profile": 42 // Struct yerine sadece ID
}
Reflection Kullanımı ¶
Bu method, Go'nun reflection paketini kullanır: - reflect.ValueOf(): Değeri reflection value'ya çevirir - v.Kind(): Değerin tipini kontrol eder (Ptr, Struct) - v.Elem(): Pointer'ı dereference eder - v.FieldByName(): Struct alanını isimle bulur - idField.Interface(): Reflection value'yu interface{}'e çevirir
Önemli Notlar ¶
- ID alanı bulunamazsa, Data değişmeden kalır - ID alanı private ise (küçük harfle başlıyorsa) erişilemez - ID alanı exported olmalıdır (büyük harfle başlamalı) - Nil pointer'lar güvenli şekilde işlenir
Performans ¶
- Reflection kullanımı nedeniyle normal field access'ten yavaştır - Ancak, serialization için gereklidir - Büyük veri setlerinde dikkat edilmeli - Cache mekanizması ile optimize edilebilir
Hata Durumları ¶
Method, aşağıdaki durumlarda sessizce başarısız olur: - ID alanı bulunamazsa (Data değişmez) - ID alanı private ise (erişilemez) - Veri tipi desteklenmiyorsa (Data değişmez)
Alternatif Yaklaşımlar ¶
**Manuel ID Extraction:**
if user.Profile.ID != 0 {
field.Data = user.Profile.ID
}
**Interface Method:**
type IDGetter interface {
GetID() uint
}
**Struct Tag:**
Profile Profile `json:"profile_id,omitempty"`
Uyarılar ¶
- Reflection kullanımı runtime overhead ekler - Type assertion başarısız olabilir - ID alanı yoksa sessizce başarısız olur - Panic riski düşük ama mevcut (invalid reflection operations)
Parametreler:
- resource: Extract edilecek resource (struct veya pointer)
func (*HasOneField) ForeignKey ¶
func (h *HasOneField) ForeignKey(key string) *HasOneField
ForeignKey, foreign key sütun adını ayarlar.
Bu method, ilişkili tablodaki foreign key sütununun adını özelleştirmenizi sağlar. Varsayılan olarak, foreign key "{slug}_id" formatında oluşturulur.
Parametreler ¶
- **key**: Foreign key sütun adı (örn. "user_id", "owner_id", "parent_id")
Kullanım Senaryoları ¶
- **Özel İsimlendirme**: Standart dışı foreign key isimleri kullanma - **Legacy Veritabanları**: Mevcut veritabanı şemalarına uyum sağlama - **Çoklu İlişkiler**: Aynı tabloya birden fazla ilişki tanımlama
Kullanım Örneği ¶
// Standart kullanım
field := fields.HasOne("Profile", "profile", "profiles").
ForeignKey("user_id")
// Özel isimlendirme
field := fields.HasOne("Manager", "manager", "users").
ForeignKey("manager_user_id")
// Legacy veritabanı
field := fields.HasOne("Invoice", "invoice", "invoices").
ForeignKey("order_fk")
GORM Entegrasyonu ¶
Bu ayar, GORM'un `foreignKey` tag'i ile senkronize edilir:
type User struct {
ID uint
Profile Profile `gorm:"foreignKey:user_id"`
}
Önemli Notlar ¶
- Foreign key sütunu ilişkili tabloda mevcut olmalıdır - Sütun tipi, owner key ile uyumlu olmalıdır (genellikle uint veya int) - Index eklenmesi performans için önerilir - Foreign key constraint'leri veritabanı seviyesinde tanımlanmalıdır
Döndürür:
- Yapılandırılmış HasOneField pointer'ı (method chaining için)
func (*HasOneField) GetDisplayKey ¶
func (h *HasOneField) GetDisplayKey() string
GetDisplayKey, display key'i döndürür (HasOne için kullanılmaz).
Bu method, HasOne ilişkisinde kullanılmaz ve boş string döndürür. Display key, genellikle HasMany ve BelongsToMany gibi çoklu kayıt ilişkilerinde hangi alanın gösterileceğini belirtmek için kullanılır.
Dönüş Değeri ¶
- Boş string ("") - HasOne için display key kavramı geçerli değildir
Neden Kullanılmaz? ¶
HasOne ilişkisi tek bir kayıt döndürdüğü için, display key'e ihtiyaç yoktur. Display key, çoklu kayıtların listesinde hangi alanın gösterileceğini belirlemek için kullanılır.
Display Key Kullanılan İlişkiler ¶
**HasMany:** - Birden fazla kayıt döndürür - Her kayıt için display key ile gösterim yapılır - Örnek: User -> Posts (post.title gösterilir)
**BelongsToMany:** - Çok-çok ilişkide birden fazla kayıt - Pivot tablo üzerinden display key kullanılır - Örnek: User -> Roles (role.name gösterilir)
**MorphMany:** - Polimorfik bir-çok ilişki - Display key ile kayıtlar listelenir - Örnek: Post -> Comments (comment.body gösterilir)
HasOne vs HasMany Karşılaştırması ¶
**HasOne (Bu Method):**
field := fields.HasOne("Profile", "profile", "profiles")
displayKey := field.GetDisplayKey() // "" (boş)
// Tek kayıt döndürür, display key gerekmez
**HasMany:**
field := fields.HasMany("Posts", "posts", "posts").
DisplayKey("title")
displayKey := field.GetDisplayKey() // "title"
// Birden fazla kayıt, her biri title ile gösterilir
Interface Implementation ¶
Bu method, Relationship interface'ini implement eder:
type Relationship interface {
GetDisplayKey() string // Bu method
GetSearchableColumns() []string
// ... diğer method'lar
}
Kullanım Örneği ¶
field := fields.HasOne("Profile", "profile", "profiles")
displayKey := field.GetDisplayKey()
fmt.Println(displayKey) // Output: "" (boş string)
// Tip kontrolü
if displayKey == "" {
fmt.Println("Display key not used for HasOne")
}
JSON Serialization ¶
API response'da bu alan genellikle dahil edilmez:
{
"name": "Profile",
"key": "profile",
"type": "relationship",
"relationship_type": "hasOne",
"related_resource": "profiles"
// display_key yok (boş olduğu için)
}
Alternatif Yaklaşımlar ¶
HasOne için display key yerine, ilişkili kaydın tamamı döndürülür:
// API Response
{
"id": 1,
"name": "John",
"profile": {
"id": 42,
"full_name": "John Doe",
"avatar": "avatar.jpg"
}
}
Önemli Notlar ¶
- Her zaman boş string döndürür - HasOne için display key kavramı geçerli değildir - Çoklu kayıt ilişkilerinde (HasMany, BelongsToMany) kullanılır - Interface uyumluluğu için implement edilmiştir
Best Practices ¶
HasOne ilişkisinde display key kullanmayın:
// Yanlış (etkisiz)
field := fields.HasOne("Profile", "profile", "profiles").
DisplayKey("full_name") // HasOne'da DisplayKey method'u yok
// Doğru
field := fields.HasOne("Profile", "profile", "profiles")
// Display key gerekmez, tüm profile objesi döndürülür
Performans ¶
- O(1) kompleksitesi (sabit string dönüşü) - Bellek allocation yok - Çok hızlı çalışır
Döndürür:
- Boş string ("") - HasOne için kullanılmaz
func (*HasOneField) GetForeignKeyColumn ¶
func (h *HasOneField) GetForeignKeyColumn() string
GetForeignKeyColumn, foreign key sütun adını döndürür.
Bu metod, HasOne ilişkisinde kullanılan foreign key sütununun adını döndürür. Foreign key, ilişkili tablodaki referans sütunudur.
Dönüş Değeri ¶
- Foreign key sütun adı (örn. "user_id", "order_id", "country_id")
Kullanım Örneği ¶
field := fields.HasOne("Profile", "profile", "profiles").ForeignKey("user_id")
foreignKey := field.GetForeignKeyColumn() // "user_id"
Döndürür:
- Foreign key sütun adı
func (*HasOneField) GetHoverCard ¶
func (h *HasOneField) GetHoverCard() *HoverCardConfig
GetHoverCard, hover card konfigürasyonunu döndürür.
Bu metod, hover card konfigürasyonunu alır.
Döndürür:
- HoverCardConfig pointer'ı (nil olabilir)
func (*HasOneField) GetLoadingStrategy ¶
func (h *HasOneField) GetLoadingStrategy() LoadingStrategy
GetLoadingStrategy, yükleme stratejisini döndürür.
Bu method, HasOne ilişkisinin yükleme stratejisini (eager veya lazy loading) döndürür. Eğer strateji ayarlanmamışsa, varsayılan olarak EAGER_LOADING döndürür.
Dönüş Değeri ¶
- LoadingStrategy: EAGER_LOADING veya LAZY_LOADING - Varsayılan: EAGER_LOADING (N+1 sorgu problemini önlemek için)
Loading Strategy Tipleri ¶
**EAGER_LOADING:** - İlişkili kayıtlar ana kayıtlarla birlikte yüklenir - N+1 sorgu problemini önler - Liste görünümlerinde önerilir - Performanslı toplu yükleme
**LAZY_LOADING:** - İlişkili kayıtlar sadece gerektiğinde yüklenir - İsteğe bağlı yükleme - Tek kayıt görünümlerinde kullanılabilir - N+1 problem riski vardır
Kullanım Senaryoları ¶
- **Query Optimization**: Sorgu stratejisini belirleme - **Preload Decision**: Preload yapılıp yapılmayacağına karar verme - **Performance Tuning**: Performans optimizasyonu için strateji seçimi - **Dynamic Loading**: Runtime'da yükleme stratejisini kontrol etme - **Debugging**: Yükleme stratejisini loglama ve debug etme
Kullanım Örneği ¶
// Eager loading ile field
field := fields.HasOne("Profile", "profile", "profiles").
WithEagerLoad()
strategy := field.GetLoadingStrategy()
fmt.Println(strategy) // Output: EAGER_LOADING
// Lazy loading ile field
field := fields.HasOne("Profile", "profile", "profiles").
WithLazyLoad()
strategy := field.GetLoadingStrategy()
fmt.Println(strategy) // Output: LAZY_LOADING
// Varsayılan (strateji ayarlanmamış)
field := fields.HasOne("Profile", "profile", "profiles")
strategy := field.GetLoadingStrategy()
fmt.Println(strategy) // Output: EAGER_LOADING (varsayılan)
Strateji Bazlı Query Execution ¶
func loadRelationships(fields []*HasOneField, items []interface{}) {
for _, field := range fields {
strategy := field.GetLoadingStrategy()
switch strategy {
case EAGER_LOADING:
// Tüm kayıtları tek sorguda yükle
preloadRelationships(field, items)
case LAZY_LOADING:
// Her kayıt için ayrı ayrı yükle (gerektiğinde)
// Hiçbir şey yapma, isteğe bağlı yükleme
}
}
}
Eager Loading Implementation ¶
if field.GetLoadingStrategy() == EAGER_LOADING {
// GORM Preload kullan
db.Preload(field.Key).Find(&users)
// Veya manuel batch loading
ownerIDs := extractOwnerIDs(users)
profiles := loadProfilesByOwnerIDs(ownerIDs)
mapProfilesToUsers(users, profiles)
}
Lazy Loading Implementation ¶
if field.GetLoadingStrategy() == LAZY_LOADING {
// İlişki sadece erişildiğinde yüklenir
// Hiçbir şey yapma, manuel yükleme gerekir
for _, user := range users {
if needsProfile(user) {
profile, _ := field.ResolveRelationship(user)
user.Profile = profile
}
}
}
Varsayılan Davranış ¶
Strateji ayarlanmamışsa (boş string), varsayılan olarak EAGER_LOADING döndürülür:
field := fields.HasOne("Profile", "profile", "profiles")
// LoadingStrategy field'ı boş string
strategy := field.GetLoadingStrategy()
// EAGER_LOADING döndürür (varsayılan)
Bu, N+1 sorgu problemini önlemek için güvenli bir varsayılandır.
Performans Karşılaştırması ¶
**100 Kullanıcı + Profilleri:**
**Eager Loading:** - Sorgu sayısı: 2 (users + profiles) - Süre: ~50ms - Bellek: Yüksek (tüm veriler)
**Lazy Loading:** - Sorgu sayısı: 101 (users + 100 profile sorgusu) - Süre: ~500ms (10x yavaş) - Bellek: Düşük (sadece gerekli veriler)
Strateji Seçim Rehberi ¶
**Eager Loading Kullan:** - Liste görünümlerinde (index, table) - İlişkili veri kesinlikle gerekli - Birden fazla kayıt işlenirken - API response'larında - Export/raporlama işlemlerinde
**Lazy Loading Kullan:** - Tek kayıt görünümlerinde (show, detail) - İlişkili veri nadiren gerekli - Bellek kısıtlı ortamlarda - Çok büyük ilişkili veri setlerinde - Koşullu veri yükleme senaryolarında
Dynamic Strategy Selection ¶
Runtime'da strateji değiştirilebilir:
func getLoadingStrategy(context Context) LoadingStrategy {
if context.IsBulkOperation() {
return EAGER_LOADING
}
if context.IsSingleRecord() {
return LAZY_LOADING
}
return EAGER_LOADING // Varsayılan
}
Monitoring ve Logging ¶
strategy := field.GetLoadingStrategy()
log.Info("Loading relationship",
"field", field.Name,
"strategy", strategy,
"record_count", len(items))
if strategy == LAZY_LOADING {
log.Warn("Lazy loading may cause N+1 queries",
"field", field.Name)
}
Testing ¶
// Test eager loading
field := fields.HasOne("Profile", "profile", "profiles").
WithEagerLoad()
assert.Equal(t, EAGER_LOADING, field.GetLoadingStrategy())
// Test lazy loading
field = fields.HasOne("Profile", "profile", "profiles").
WithLazyLoad()
assert.Equal(t, LAZY_LOADING, field.GetLoadingStrategy())
// Test default
field = fields.HasOne("Profile", "profile", "profiles")
assert.Equal(t, EAGER_LOADING, field.GetLoadingStrategy())
Önemli Notlar ¶
- Varsayılan strateji EAGER_LOADING'dir (güvenli seçim) - Boş string kontrolü yapılır ve varsayılan döndürülür - Strateji WithEagerLoad() veya WithLazyLoad() ile ayarlanır - Liste görünümlerinde mutlaka eager loading kullanın - N+1 problemini önlemek için varsayılan eager'dır
Best Practices ¶
**Liste Görünümlerinde:**
field := fields.HasOne("Profile", "profile", "profiles").
WithEagerLoad() // Açıkça belirt
**Tek Kayıt Görünümlerinde:**
field := fields.HasOne("Profile", "profile", "profiles").
WithLazyLoad() // Gerektiğinde yükle
**Varsayılana Güvenme:**
// Kötü: Strateji belirsiz
field := fields.HasOne("Profile", "profile", "profiles")
// İyi: Strateji açıkça belirtilmiş
field := fields.HasOne("Profile", "profile", "profiles").
WithEagerLoad()
Performans İpuçları ¶
- Production'da eager loading tercih edin - Lazy loading sadece gerektiğinde kullanın - Sorgu sayısını monitor edin - N+1 problemini tespit edin ve düzeltin - Cache mekanizması ile optimize edin
Uyarılar ¶
- Lazy loading N+1 sorgu problemine yol açar - Liste görünümlerinde lazy loading kullanmayın - Varsayılan eager olsa da açıkça belirtmek daha iyidir - Strateji değişikliği tüm sorguları etkiler
Döndürür:
- LoadingStrategy: EAGER_LOADING veya LAZY_LOADING (varsayılan: EAGER_LOADING)
func (*HasOneField) GetOwnerKeyColumn ¶
func (h *HasOneField) GetOwnerKeyColumn() string
GetOwnerKeyColumn, owner key sütun adını döndürür.
Bu metod, HasOne ilişkisinde kullanılan owner key sütununun adını döndürür. Owner key, ana tablodaki referans sütunudur (genellikle primary key).
Dönüş Değeri ¶
- Owner key sütun adı (örn. "id", "uuid")
Kullanım Örneği ¶
field := fields.HasOne("Profile", "profile", "profiles").OwnerKey("id")
ownerKey := field.GetOwnerKeyColumn() // "id"
Döndürür:
- Owner key sütun adı
func (*HasOneField) GetQueryCallback ¶
func (h *HasOneField) GetQueryCallback() func(interface{}) interface{}
GetQueryCallback, query callback fonksiyonunu döndürür.
Bu method, ilişki sorgusunu özelleştirmek için tanımlanmış callback fonksiyonunu döndürür. Eğer callback tanımlanmamışsa, varsayılan olarak sorguyu değiştirmeyen bir fonksiyon döndürür.
Dönüş Değeri ¶
- Query callback fonksiyonu: func(interface{}) interface{} - Callback yoksa: Sorguyu olduğu gibi döndüren varsayılan fonksiyon
Çalışma Mantığı ¶
1. QueryCallback field'ını kontrol eder 2. Eğer nil ise, varsayılan pass-through fonksiyon döndürür 3. Eğer tanımlıysa, kullanıcı tarafından ayarlanan callback'i döndürür
Kullanım Senaryoları ¶
- **Query Execution**: İlişki yüklenirken callback'i uygulama - **Dynamic Filtering**: Runtime'da sorgu özelleştirme - **Middleware**: Sorgu pipeline'ına ekleme - **Logging**: Sorgu loglaması için callback kullanma - **Testing**: Mock callback'ler ile test etme
Kullanım Örneği ¶
// Callback tanımlı field
field := fields.HasOne("Profile", "profile", "profiles").
Query(func(q interface{}) interface{} {
return q.(*gorm.DB).Where("status = ?", "active")
})
// Callback'i al ve kullan
callback := field.GetQueryCallback()
query := db.Model(&Profile{})
query = callback(query).(*gorm.DB)
query.Find(&profiles)
Varsayılan Callback ¶
Callback tanımlanmamışsa, varsayılan fonksiyon döndürülür:
func(q interface{}) interface{} {
return q // Sorguyu olduğu gibi döndür
}
Bu, callback kontrolü yapmadan güvenle kullanılabilir:
// Her zaman çalışır (nil check gerekmez) callback := field.GetQueryCallback() query = callback(query)
Callback Tanımlama ¶
Query method'u ile callback tanımlanır:
field.Query(func(q interface{}) interface{} {
db := q.(*gorm.DB)
return db.Where("verified = ?", true).
Order("created_at DESC")
})
Callback Uygulama ¶
**Eager Loading'de:**
func loadRelationship(field *HasOneField, ownerID uint) interface{} {
query := db.Model(&Profile{}).
Where("user_id = ?", ownerID)
// Callback uygula
callback := field.GetQueryCallback()
query = callback(query).(*gorm.DB)
var profile Profile
query.First(&profile)
return profile
}
**Lazy Loading'de:**
func (h *HasOneField) ResolveRelationship(item interface{}) (interface{}, error) {
ownerValue := extractFieldValue(item, h.OwnerKeyColumn)
query := db.Model(relatedModel).
Where(fmt.Sprintf("%s = ?", h.ForeignKeyColumn), ownerValue)
// Callback uygula
callback := h.GetQueryCallback()
query = callback(query).(*gorm.DB)
var result interface{}
err := query.First(&result).Error
return result, err
}
Callback Chaining ¶
Birden fazla callback zincirleme yapılabilir:
baseCallback := field.GetQueryCallback()
enhancedCallback := func(q interface{}) interface{} {
// Önce base callback uygula
q = baseCallback(q)
// Sonra ek işlemler
return q.(*gorm.DB).Limit(10)
}
Type Safety ¶
Callback içinde type assertion kullanılır:
callback := func(q interface{}) interface{} {
db, ok := q.(*gorm.DB)
if !ok {
return q // Type assertion başarısız, olduğu gibi döndür
}
return db.Where("active = ?", true)
}
Testing ¶
Test'lerde mock callback kullanılabilir:
// Test setup
mockCallback := func(q interface{}) interface{} {
// Mock davranış
return q
}
field := fields.HasOne("Profile", "profile", "profiles").
Query(mockCallback)
// Test
callback := field.GetQueryCallback()
assert.NotNil(t, callback)
Önemli Notlar ¶
- Method her zaman nil olmayan bir fonksiyon döndürür - Varsayılan callback sorguyu değiştirmez (pass-through) - Callback nil kontrolü yapmanıza gerek yoktur - Type assertion başarısız olursa panic riski vardır - Callback içinde error handling yapılmalıdır
Best Practices ¶
**Güvenli Type Assertion:**
callback := func(q interface{}) interface{} {
db, ok := q.(*gorm.DB)
if !ok {
log.Warn("Type assertion failed")
return q
}
return db.Where("active = ?", true)
}
**Error Handling:**
callback := func(q interface{}) interface{} {
defer func() {
if r := recover(); r != nil {
log.Error("Callback panic:", r)
}
}()
return q.(*gorm.DB).Where("active = ?", true)
}
**Logging:**
callback := func(q interface{}) interface{} {
log.Debug("Applying query callback")
db := q.(*gorm.DB)
return db.Where("active = ?", true)
}
Performans ¶
- O(1) kompleksitesi (field access veya varsayılan fonksiyon dönüşü) - Minimal bellek allocation - Callback execution overhead callback içeriğine bağlıdır
Uyarılar ¶
- Callback içinde panic oluşursa uygulama çökebilir - Type assertion başarısız olursa runtime error oluşur - Callback'te yapılan değişiklikler tüm sorguları etkiler - Thread-safety callback implementasyonuna bağlıdır
Döndürür:
- Query callback fonksiyonu (her zaman nil olmayan)
func (*HasOneField) GetRelatedResourceSlug ¶
func (h *HasOneField) GetRelatedResourceSlug() string
GetRelatedResource, ilişkili resource'un slug'ını döndürür.
Bu method, HasOne ilişkisinde ilişkili resource'un slug değerini döndürür. Slug, resource'u sistem içinde tanımlayan benzersiz string identifier'dır.
Dönüş Değeri ¶
- İlişkili resource'un slug'ı (örn. "profiles", "invoices", "capitals")
Kullanım Senaryoları ¶
- **Resource Lookup**: İlişkili resource'u slug ile bulma - **API Routing**: İlişkili resource'un endpoint'ini oluşturma - **Dynamic Loading**: Runtime'da ilişkili resource'u yükleme - **Validation**: İlişki tanımının doğruluğunu kontrol etme - **Metadata**: İlişki bilgilerini metadata olarak saklama
Kullanım Örneği ¶
field := fields.HasOne("Profile", "profile", "profiles")
slug := field.GetRelatedResource()
fmt.Println(slug) // Output: "profiles"
// Resource lookup
relatedResource := resourceRegistry.Get(field.GetRelatedResource())
// API endpoint oluşturma
endpoint := fmt.Sprintf("/api/%s", field.GetRelatedResource())
// Output: "/api/profiles"
// Dynamic query
tableName := field.GetRelatedResource()
db.Table(tableName).Where("user_id = ?", userID).First(&profile)
Slug Formatı ¶
Slug genellikle aşağıdaki formatlarda olur: - **Plural Form**: "profiles", "invoices", "users" - **Kebab Case**: "user-profiles", "order-items" - **Snake Case**: "user_profiles", "order_items"
Resource Instance vs String Slug ¶
HasOne oluşturulurken iki yöntem kullanılabilir:
**String Slug:**
field := fields.HasOne("Profile", "profile", "profiles")
field.GetRelatedResource() // "profiles"
**Resource Instance:**
field := fields.HasOne("Profile", "profile", user.NewProfileResource())
field.GetRelatedResource() // "profiles" (resource'un Slug() method'undan)
JSON Serialization ¶
API response'da kullanımı:
{
"name": "Profile",
"key": "profile",
"type": "relationship",
"relationship_type": "hasOne",
"related_resource": "profiles" // Bu method'un dönüş değeri
}
Interface Implementation ¶
Bu method, Relationship interface'ini implement eder:
type Relationship interface {
GetRelationshipType() string
GetRelatedResource() string // Bu method
GetRelationshipName() string
}
Resource Registry Entegrasyonu ¶
// Resource registry'den ilişkili resource'u al
type ResourceRegistry struct {
resources map[string]Resource
}
func (r *ResourceRegistry) Get(slug string) Resource {
return r.resources[slug]
}
// Kullanım
relatedResource := registry.Get(field.GetRelatedResource())
Önemli Notlar ¶
- Slug değeri HasOne oluşturulurken ayarlanır - Değer değiştirilemez (immutable) - Boş string olabilir (fallback durumunda) - Case-sensitive: "profiles" ≠ "Profiles"
Hata Durumları ¶
Eğer HasOne oluşturulurken geçersiz bir değer verilirse: - String değilse ve Slug() method'u yoksa: boş string döner - Nil değer: boş string döner
Performans ¶
- O(1) kompleksitesi (field access) - Bellek allocation yok - Çok hızlı çalışır
Döndürür:
- İlişkili resource'un slug'ı (string)
func (*HasOneField) GetRelatedTableName ¶
func (h *HasOneField) GetRelatedTableName() string
GetRelatedTableName, ilişkili tablo adını döndürür.
Bu metod, HasOne ilişkisinde kullanılan ilişkili tablonun adını döndürür. Raw SQL sorguları için kullanılır.
Dönüş Değeri ¶
- İlişkili tablo adı (örn. "profiles", "invoices", "capitals")
Kullanım Örneği ¶
field := fields.HasOne("Profile", "profile", "profiles")
tableName := field.GetRelatedTableName() // "profiles"
Döndürür:
- İlişkili tablo adı
func (*HasOneField) GetRelationshipName ¶
func (h *HasOneField) GetRelationshipName() string
GetRelationshipName, ilişkinin adını döndürür.
Bu method, HasOne ilişkisinin görünen adını (display name) döndürür. Bu ad, kullanıcı arayüzünde gösterilir ve ilişkiyi tanımlar.
Dönüş Değeri ¶
- İlişkinin görünen adı (örn. "Profile", "Invoice", "Capital")
Kullanım Senaryoları ¶
- **UI Rendering**: Form etiketlerinde ve tablo başlıklarında gösterme - **Validation Messages**: Hata mesajlarında ilişki adını kullanma - **Logging**: Log mesajlarında ilişkiyi tanımlama - **API Documentation**: API dokümantasyonunda ilişki açıklaması - **Debugging**: Debug çıktılarında ilişkiyi belirleme
Kullanım Örneği ¶
field := fields.HasOne("Profile", "profile", "profiles")
name := field.GetRelationshipName()
fmt.Println(name) // Output: "Profile"
// UI rendering
label := fmt.Sprintf("%s:", field.GetRelationshipName())
// Output: "Profile:"
// Validation message
errMsg := fmt.Sprintf("%s is required", field.GetRelationshipName())
// Output: "Profile is required"
// Form field
<label>{field.GetRelationshipName()}</label>
<select name="profile_id">...</select>
Name vs Key vs Slug ¶
HasOne ilişkisinde üç farklı identifier vardır:
**Name (GetRelationshipName):** - Görünen ad, kullanıcı dostu - Örnek: "Profile", "User Profile", "Kullanıcı Profili" - Kullanım: UI, mesajlar, dokümantasyon
**Key:** - Programatik identifier, struct field adı - Örnek: "profile", "userProfile", "user_profile" - Kullanım: Kod içinde, JSON keys, form names
**Slug (GetRelatedResource):** - Resource identifier, tablo/endpoint adı - Örnek: "profiles", "user-profiles", "user_profiles" - Kullanım: Routing, database, API endpoints
Çoklu Dil Desteği (i18n) ¶
Name değeri, çoklu dil desteği için kullanılabilir:
// İngilizce
field := fields.HasOne("Profile", "profile", "profiles")
// Türkçe
field := fields.HasOne("Profil", "profile", "profiles")
// Runtime çeviri
name := i18n.Translate(field.GetRelationshipName())
JSON Serialization ¶
API response'da kullanımı:
{
"name": "Profile", // Bu method'un dönüş değeri
"key": "profile",
"type": "relationship",
"relationship_type": "hasOne",
"related_resource": "profiles"
}
Interface Implementation ¶
Bu method, Relationship interface'ini implement eder:
type Relationship interface {
GetRelationshipType() string
GetRelatedResource() string
GetRelationshipName() string // Bu method
}
UI Kullanım Örnekleri ¶
**Form Label:**
<div class="form-group">
<label>{field.GetRelationshipName()}</label>
<select name="profile_id">
<option value="">Select {field.GetRelationshipName()}</option>
</select>
</div>
**Table Header:**
<th>{field.GetRelationshipName()}</th>
**Validation Error:**
errors := map[string]string{
"profile": fmt.Sprintf("%s is required", field.GetRelationshipName()),
}
Önemli Notlar ¶
- Name değeri HasOne oluşturulurken ayarlanır - Değer değiştirilemez (immutable) - Boş string olabilir (ancak önerilmez) - Kullanıcı dostu olmalıdır (başlık formatında)
Best Practices ¶
**İyi Örnekler:** - "Profile" (kısa, açık) - "User Profile" (açıklayıcı) - "Invoice Details" (detaylı) - "Kullanıcı Profili" (yerelleştirilmiş)
**Kötü Örnekler:** - "profile" (küçük harf, programatik) - "PROFILE" (tamamı büyük harf) - "prof" (kısaltma, belirsiz) - "user_profile" (snake_case, programatik)
Performans ¶
- O(1) kompleksitesi (field access) - Bellek allocation yok - Çok hızlı çalışır
Döndürür:
- İlişkinin görünen adı (string)
func (*HasOneField) GetRelationshipType ¶
func (h *HasOneField) GetRelationshipType() string
GetRelationshipType, ilişki tipini döndürür.
Bu method, HasOne ilişkisinin tipini string olarak döndürür. İlişki tipi, sistem içinde ilişki türünü tanımlamak ve işlemek için kullanılır.
Dönüş Değeri ¶
- "hasOne": HasOne ilişki tipini belirten sabit string
Kullanım Senaryoları ¶
- **Tip Kontrolü**: İlişki tipini runtime'da kontrol etme - **Routing**: İlişki tipine göre farklı işlemler yapma - **Serialization**: JSON/XML çıktısında ilişki tipini belirtme - **Validation**: İlişki tipine özel validasyon kuralları uygulama - **Logging**: Log mesajlarında ilişki tipini gösterme
Kullanım Örneği ¶
field := fields.HasOne("Profile", "profile", "profiles")
relType := field.GetRelationshipType()
fmt.Println(relType) // Output: "hasOne"
// Tip kontrolü
if field.GetRelationshipType() == "hasOne" {
// HasOne'a özel işlemler
}
// Switch case ile routing
switch field.GetRelationshipType() {
case "hasOne":
// HasOne işlemleri
case "hasMany":
// HasMany işlemleri
case "belongsTo":
// BelongsTo işlemleri
}
İlişki Tipleri ¶
Sistemdeki diğer ilişki tipleri: - "hasOne": Bir-bir ilişki (bu method) - "hasMany": Bir-çok ilişki - "belongsTo": Ters bir-bir veya ters bir-çok ilişki - "belongsToMany": Çok-çok ilişki - "morphTo": Polimorfik ilişki - "morphOne": Polimorfik bir-bir ilişki - "morphMany": Polimorfik bir-çok ilişki
JSON Serialization ¶
API response'da kullanımı:
{
"name": "Profile",
"key": "profile",
"type": "relationship",
"relationship_type": "hasOne",
"related_resource": "profiles"
}
Interface Implementation ¶
Bu method, Relationship interface'ini implement eder:
type Relationship interface {
GetRelationshipType() string
GetRelatedResource() string
GetRelationshipName() string
}
Önemli Notlar ¶
- Dönüş değeri her zaman "hasOne" string'idir - Değer değiştirilemez (immutable) - Case-sensitive: "hasOne" (camelCase) - Boş string döndürmez
Performans ¶
- O(1) kompleksitesi (sabit string dönüşü) - Bellek allocation yok - Çok hızlı çalışır
Döndürür:
- "hasOne" string sabiti
func (*HasOneField) GetSearchableColumns ¶
func (h *HasOneField) GetSearchableColumns() []string
GetSearchableColumns, aranabilir sütunları döndürür (HasOne için kullanılmaz).
Bu method, HasOne ilişkisinde kullanılmaz ve boş slice döndürür. Searchable columns, genellikle HasMany ve BelongsToMany gibi çoklu kayıt ilişkilerinde hangi sütunlarda arama yapılacağını belirtmek için kullanılır.
Dönüş Değeri ¶
- Boş string slice ([]string{}) - HasOne için searchable columns kavramı geçerli değildir
Neden Kullanılmaz? ¶
HasOne ilişkisi tek bir kayıt döndürdüğü için, searchable columns'a ihtiyaç yoktur. Searchable columns, çoklu kayıtların listesinde arama yapmak için kullanılır.
Searchable Columns Kullanılan İlişkiler ¶
**HasMany:** - Birden fazla kayıt döndürür - Kayıtlar arasında arama yapılabilir - Örnek: User -> Posts (title, body sütunlarında ara)
**BelongsToMany:** - Çok-çok ilişkide birden fazla kayıt - İlişkili kayıtlarda arama yapılabilir - Örnek: User -> Roles (name, description sütunlarında ara)
**MorphMany:** - Polimorfik bir-çok ilişki - Searchable columns ile kayıtlar filtrelenir - Örnek: Post -> Comments (body, author sütunlarında ara)
HasOne vs HasMany Karşılaştırması ¶
**HasOne (Bu Method):**
field := fields.HasOne("Profile", "profile", "profiles")
columns := field.GetSearchableColumns() // [] (boş)
// Tek kayıt döndürür, arama gerekmez
**HasMany:**
field := fields.HasMany("Posts", "posts", "posts").
SearchableColumns("title", "body", "excerpt")
columns := field.GetSearchableColumns() // ["title", "body", "excerpt"]
// Birden fazla kayıt, arama yapılabilir
Interface Implementation ¶
Bu method, Relationship interface'ini implement eder:
type Relationship interface {
GetDisplayKey() string
GetSearchableColumns() []string // Bu method
// ... diğer method'lar
}
Kullanım Örneği ¶
field := fields.HasOne("Profile", "profile", "profiles")
columns := field.GetSearchableColumns()
fmt.Println(len(columns)) // Output: 0 (boş slice)
// Tip kontrolü
if len(columns) == 0 {
fmt.Println("Searchable columns not used for HasOne")
}
JSON Serialization ¶
API response'da bu alan genellikle dahil edilmez:
{
"name": "Profile",
"key": "profile",
"type": "relationship",
"relationship_type": "hasOne",
"related_resource": "profiles"
// searchable_columns yok (boş olduğu için)
}
Alternatif Yaklaşımlar ¶
HasOne için arama yerine, ilişkili kaydın tamamı döndürülür ve frontend'de filtreleme yapılabilir:
// API Response
{
"id": 1,
"name": "John",
"profile": {
"id": 42,
"full_name": "John Doe",
"bio": "Software Developer"
}
}
// Frontend'de filtreleme
if (user.profile.full_name.includes(searchTerm)) {
// Göster
}
Global Search ¶
HasOne ilişkisi global search'e dahil edilebilir:
field := fields.HasOne("Profile", "profile", "profiles").
Searchable() // Global search'e dahil et
// Ancak bu, ilişkili kaydın kendisini değil,
// ilişkinin varlığını aranabilir yapar
Önemli Notlar ¶
- Her zaman boş slice döndürür - HasOne için searchable columns kavramı geçerli değildir - Çoklu kayıt ilişkilerinde (HasMany, BelongsToMany) kullanılır - Interface uyumluluğu için implement edilmiştir - Nil değil, boş slice döndürür ([]string{})
Best Practices ¶
HasOne ilişkisinde searchable columns kullanmayın:
// Yanlış (etkisiz)
field := fields.HasOne("Profile", "profile", "profiles").
SearchableColumns("full_name", "bio") // HasOne'da bu method yok
// Doğru
field := fields.HasOne("Profile", "profile", "profiles")
// Searchable columns gerekmez, tek kayıt döndürülür
Performans ¶
- O(1) kompleksitesi (sabit slice dönüşü) - Minimal bellek allocation (boş slice) - Çok hızlı çalışır
Döndürür:
- Boş string slice ([]string{}) - HasOne için kullanılmaz
func (*HasOneField) GetTypes ¶
func (h *HasOneField) GetTypes() map[string]string
GetTypes, tip eşlemelerini döndürür (HasOne için kullanılmaz).
Bu method, HasOne ilişkisinde kullanılmaz ve boş map döndürür. Type mappings, genellikle form field'larında input tiplerini ve validasyon kurallarını tanımlamak için kullanılır.
Dönüş Değeri ¶
- Boş map (map[string]string{}) - HasOne için type mappings kavramı geçerli değildir
Neden Kullanılmaz? ¶
HasOne ilişkisi bir relationship field'dır ve primitive tip mapping'e ihtiyaç duymaz. Type mappings, genellikle Text, Number, Email gibi primitive field'larda input tipini ve validasyon kurallarını belirtmek için kullanılır.
Type Mappings Kullanılan Field'lar ¶
**Text Field:**
field := fields.Text("Name", "name")
types := field.GetTypes()
// {"input": "text", "validation": "string"}
**Number Field:**
field := fields.Number("Age", "age")
types := field.GetTypes()
// {"input": "number", "validation": "integer"}
**Email Field:**
field := fields.Email("Email", "email")
types := field.GetTypes()
// {"input": "email", "validation": "email"}
**Date Field:**
field := fields.Date("Birth Date", "birth_date")
types := field.GetTypes()
// {"input": "date", "validation": "date"}
HasOne vs Primitive Fields Karşılaştırması ¶
**HasOne (Bu Method):**
field := fields.HasOne("Profile", "profile", "profiles")
types := field.GetTypes() // {} (boş map)
// İlişki field'ı, tip mapping gerekmez
**Text Field:**
field := fields.Text("Name", "name")
types := field.GetTypes() // {"input": "text", "validation": "string"}
// Primitive field, tip mapping gerekir
Interface Implementation ¶
Bu method, Field interface'ini implement eder:
type Field interface {
GetTypes() map[string]string
// ... diğer method'lar
}
Kullanım Örneği ¶
field := fields.HasOne("Profile", "profile", "profiles")
types := field.GetTypes()
fmt.Println(len(types)) // Output: 0 (boş map)
// Tip kontrolü
if len(types) == 0 {
fmt.Println("Type mappings not used for HasOne")
}
JSON Serialization ¶
API response'da bu alan genellikle dahil edilmez:
{
"name": "Profile",
"key": "profile",
"type": "relationship",
"relationship_type": "hasOne",
"related_resource": "profiles"
// types yok (boş olduğu için)
}
Type Mappings Kullanım Alanları ¶
Type mappings, aşağıdaki alanlarda kullanılır:
**Frontend Rendering:** - HTML input type belirleme - Form validation kuralları - Input maskeleme (telefon, kredi kartı vb.)
**Backend Validation:** - Veri tipi kontrolü - Format validasyonu - Type casting
**Database Schema:** - Sütun tipi belirleme - Migration oluşturma - Index stratejisi
HasOne İçin Alternatif ¶
HasOne ilişkisinde tip bilgisi farklı şekilde saklanır:
// İlişki tipi field.GetRelationshipType() // "hasOne" // Field tipi field.Type // TYPE_RELATIONSHIP // View component field.View // "has-one-field"
Frontend Component Selection ¶
Frontend'de component seçimi View field'ına göre yapılır:
// HasOne için
switch field.View {
case "has-one-field":
return <HasOneSelect field={field} />
case "text-field":
return <TextInput field={field} />
case "number-field":
return <NumberInput field={field} />
}
Type Mappings Örneği (Diğer Field'lar) ¶
**Text Field:**
{
"input": "text",
"validation": "string",
"html_type": "text",
"db_type": "VARCHAR"
}
**Number Field:**
{
"input": "number",
"validation": "integer",
"html_type": "number",
"db_type": "INT"
}
**Email Field:**
{
"input": "email",
"validation": "email",
"html_type": "email",
"db_type": "VARCHAR"
}
Önemli Notlar ¶
- Her zaman boş map döndürür - HasOne için type mappings kavramı geçerli değildir - Primitive field'larda (Text, Number, Email) kullanılır - Interface uyumluluğu için implement edilmiştir - Nil değil, boş map döndürür (map[string]string{})
Best Practices ¶
HasOne ilişkisinde type mappings kullanmayın:
// Yanlış (etkisiz)
types := field.GetTypes()
if types["input"] == "text" {
// HasOne için bu kontrol anlamsız
}
// Doğru
if field.GetRelationshipType() == "hasOne" {
// HasOne'a özel işlemler
}
Field Type Kontrolü ¶
Field tipini kontrol etmek için doğru method'ları kullanın:
// HasOne için
if field.Type == TYPE_RELATIONSHIP {
relType := field.GetRelationshipType() // "hasOne"
}
// Primitive field için
if field.Type == TYPE_TEXT {
types := field.GetTypes() // {"input": "text", ...}
}
Migration ve Schema ¶
HasOne için database schema bilgisi farklı şekilde alınır:
// Foreign key bilgisi foreignKey := field.ForeignKeyColumn // "user_id" ownerKey := field.OwnerKeyColumn // "id" // Migration ALTER TABLE profiles ADD CONSTRAINT fk_profiles_user_id FOREIGN KEY (user_id) REFERENCES users(id);
Performans ¶
- O(1) kompleksitesi (boş map dönüşü) - Minimal bellek allocation (boş map) - Çok hızlı çalışır
Interface Uyumluluğu ¶
Bu method, Field interface'ini implement etmek için gereklidir:
type Field interface {
GetTypes() map[string]string // Tüm field'lar implement etmeli
GetName() string
GetKey() string
// ... diğer method'lar
}
HasOne bir Field olduğu için bu method'u implement etmelidir, ancak relationship field'lar için type mappings kullanılmaz.
Debugging ¶
Field tipini debug ederken:
fmt.Printf("Field: %s\n", field.Name)
fmt.Printf("Type: %s\n", field.Type)
fmt.Printf("View: %s\n", field.View)
if field.Type == TYPE_RELATIONSHIP {
fmt.Printf("Relationship Type: %s\n", field.GetRelationshipType())
fmt.Printf("Related Resource: %s\n", field.GetRelatedResource())
} else {
fmt.Printf("Types: %+v\n", field.GetTypes())
}
Uyarılar ¶
- HasOne için GetTypes() kullanmayın (her zaman boş) - Tip bilgisi için GetRelationshipType() kullanın - Frontend component seçimi için View field'ını kullanın - Database schema için ForeignKeyColumn ve OwnerKeyColumn kullanın
Döndürür:
- Boş map (map[string]string{}) - HasOne için kullanılmaz
func (*HasOneField) HoverCard ¶
func (h *HasOneField) HoverCard(hoverStruct interface{}) *HasOneField
HoverCard, hover card struct'ını ayarlar ve hover card'ı etkinleştirir.
Bu metod, hover card için kullanılacak struct'ı belirler ve hover card özelliğini aktif eder.
Parametreler ¶
- **hoverStruct**: Hover card verisi için kullanılacak struct (örn. &ProfileHoverCard{})
Kullanım Örneği ¶
type ProfileHoverCard struct {
Avatar string `json:"avatar"`
Bio string `json:"bio"`
Location string `json:"location"`
}
field := fields.HasOne("Profile", "profile", "profiles").
ForeignKey("user_id").
HoverCard(&ProfileHoverCard{})
Döndürür:
- HasOneField pointer'ı (method chaining için)
func (*HasOneField) IsRequired ¶
func (h *HasOneField) IsRequired() bool
IsRequired, alanın zorunlu olup olmadığını döndürür.
Bu method, HasOne ilişkisinin zorunlu (required) olarak işaretlenip işaretlenmediğini kontrol eder. Zorunlu alan, form validasyonunda ve veri kaydında mutlaka doldurulması gereken alandır.
Dönüş Değeri ¶
- true: Alan zorunludur, mutlaka doldurulmalıdır - false: Alan opsiyoneldir, boş bırakılabilir
Kullanım Senaryoları ¶
- **Form Validation**: Form gönderilmeden önce zorunlu alan kontrolü - **API Validation**: Request payload validasyonu - **Database Constraints**: NOT NULL constraint kontrolü - **UI Rendering**: Zorunlu alanları görsel olarak işaretleme (*) - **Error Messages**: Zorunlu alan hata mesajları
Kullanım Örneği ¶
// Zorunlu HasOne field
field := fields.HasOne("Profile", "profile", "profiles").
Required()
// Zorunluluk kontrolü
if field.IsRequired() {
fmt.Println("Profile is required")
}
// Form validation
if field.IsRequired() && profileID == 0 {
return errors.New("Profile is required")
}
Required Method ile Kullanım ¶
Alanı zorunlu yapmak için Required() method'u kullanılır:
field := fields.HasOne("Profile", "profile", "profiles").
Required() // IsRequired field'ını true yapar
fmt.Println(field.IsRequired()) // Output: true
Validation Implementation ¶
func validateField(field *HasOneField, value interface{}) error {
if field.IsRequired() {
if value == nil {
return fmt.Errorf("%s is required", field.Name)
}
// ID kontrolü
if id, ok := value.(uint); ok && id == 0 {
return fmt.Errorf("%s is required", field.Name)
}
}
return nil
}
Frontend Integration ¶
Frontend'de zorunlu alanlar otomatik olarak işaretlenir:
// API Response
{
"name": "Profile",
"key": "profile",
"type": "relationship",
"required": true // Bu method'un dönüş değeri
}
// Frontend Rendering
<label>
Profile {field.required && <span className="text-red-500">*</span>}
</label>
<select name="profile_id" required={field.required}>
<option value="">Select Profile</option>
</select>
Form Validation Örneği ¶
// Backend validation
func validateUserForm(data map[string]interface{}, fields []*HasOneField) error {
for _, field := range fields {
if field.IsRequired() {
value, exists := data[field.Key]
if !exists || value == nil {
return fmt.Errorf("%s is required", field.Name)
}
}
}
return nil
}
// Kullanım
err := validateUserForm(formData, userFields)
if err != nil {
return err
}
Database Constraints ¶
Zorunlu alan, veritabanında NOT NULL constraint ile eşleşir:
// Migration
if field.IsRequired() {
// Foreign key NOT NULL olmalı
ALTER TABLE profiles
ADD CONSTRAINT fk_profiles_user_id
FOREIGN KEY (user_id) REFERENCES users(id)
NOT NULL;
}
Error Messages ¶
Zorunlu alan için hata mesajları:
if field.IsRequired() && value == nil {
return map[string]string{
field.Key: fmt.Sprintf("%s is required", field.Name),
}
}
// Örnek çıktı
{
"profile": "Profile is required"
}
UI Rendering ¶
**Form Label:**
<label htmlFor="profile_id">
{field.Name}
{field.IsRequired() && <span className="text-red-500">*</span>}
</label>
**Input Field:**
<select
id="profile_id"
name="profile_id"
required={field.IsRequired()}
className={field.IsRequired() ? "required" : ""}
>
<option value="">Select {field.Name}</option>
</select>
**Validation Message:**
{errors.profile && (
<span className="error">
{field.Name} is required
</span>
)}
API Validation ¶
// Request handler
func createUser(c *gin.Context) {
var data map[string]interface{}
c.BindJSON(&data)
// Validate required fields
for _, field := range userResource.Fields() {
if hasOneField, ok := field.(*HasOneField); ok {
if hasOneField.IsRequired() {
value, exists := data[hasOneField.Key]
if !exists || value == nil {
c.JSON(400, gin.H{
"error": fmt.Sprintf("%s is required", hasOneField.Name),
})
return
}
}
}
}
// Create user
// ...
}
Testing ¶
// Test required field
func TestHasOneRequired(t *testing.T) {
field := fields.HasOne("Profile", "profile", "profiles").
Required()
assert.True(t, field.IsRequired())
}
// Test optional field
func TestHasOneOptional(t *testing.T) {
field := fields.HasOne("Profile", "profile", "profiles")
assert.False(t, field.IsRequired())
}
Önemli Notlar ¶
- Schema.IsRequired field'ından değer okunur - Varsayılan olarak false'dur (opsiyonel) - Required() method'u ile true yapılır - Frontend ve backend validasyonunda kullanılır - Database constraint'leri ile senkronize olmalıdır
Best Practices ¶
**Zorunlu İlişkiler:**
// İyi: Açıkça required olarak işaretle
field := fields.HasOne("Profile", "profile", "profiles").
Required()
// Kötü: Varsayılana güvenme
field := fields.HasOne("Profile", "profile", "profiles")
// IsRequired() false döner
**Validation:**
// İyi: Hem frontend hem backend validation // Frontend: HTML5 required attribute // Backend: IsRequired() kontrolü // Kötü: Sadece frontend validation // Güvenlik riski, bypass edilebilir
**Error Messages:**
// İyi: Kullanıcı dostu mesaj
if field.IsRequired() && value == nil {
return fmt.Errorf("%s is required", field.Name)
}
// Kötü: Teknik mesaj
if field.IsRequired() && value == nil {
return errors.New("validation failed: nil value")
}
Database Migration ¶
// Required field için migration
if field.IsRequired() {
sql := fmt.Sprintf(`
ALTER TABLE %s
MODIFY COLUMN %s INT NOT NULL
`, tableName, field.ForeignKeyColumn)
db.Exec(sql)
}
Conditional Required ¶
Bazı durumlarda koşullu zorunluluk gerekebilir:
// Örnek: Profil sadece verified kullanıcılar için zorunlu
func validateProfile(user User, profileID uint) error {
field := fields.HasOne("Profile", "profile", "profiles")
if user.Verified && field.IsRequired() {
if profileID == 0 {
return errors.New("Profile is required for verified users")
}
}
return nil
}
Performans ¶
- O(1) kompleksitesi (field access) - Bellek allocation yok - Çok hızlı çalışır
Uyarılar ¶
- Required field'lar mutlaka doldurulmalıdır - Frontend validation bypass edilebilir, backend validation şarttır - Database constraint'leri ile senkronize olmalıdır - Migration'larda NOT NULL constraint eklenmelidir - Mevcut verilerde NULL değer varsa migration başarısız olur
Döndürür:
- true: Alan zorunludur
- false: Alan opsiyoneldir
func (*HasOneField) OwnerKey ¶
func (h *HasOneField) OwnerKey(key string) *HasOneField
OwnerKey, owner key sütun adını ayarlar.
Bu method, ana tablodaki (parent table) referans sütununun adını özelleştirmenizi sağlar. Varsayılan olarak, owner key "id" (primary key) olarak ayarlanır.
Parametreler ¶
- **key**: Owner key sütun adı (örn. "id", "uuid", "code")
Kullanım Senaryoları ¶
- **UUID Primary Key**: UUID kullanan tablolarda - **Composite Keys**: Birleşik anahtar kullanımında - **Custom Primary Keys**: Özel primary key isimlendirmelerinde - **Legacy Sistemler**: Standart dışı primary key yapılarında
Kullanım Örneği ¶
// UUID primary key
field := fields.HasOne("Profile", "profile", "profiles").
ForeignKey("user_uuid").
OwnerKey("uuid")
// Özel primary key
field := fields.HasOne("Invoice", "invoice", "invoices").
ForeignKey("order_code").
OwnerKey("order_code")
// Composite key senaryosu
field := fields.HasOne("Detail", "detail", "details").
ForeignKey("parent_id").
OwnerKey("custom_id")
GORM Entegrasyonu ¶
Bu ayar, GORM'un `references` tag'i ile senkronize edilir:
type User struct {
UUID string `gorm:"primaryKey"`
Profile Profile `gorm:"foreignKey:user_uuid;references:uuid"`
}
Önemli Notlar ¶
- Owner key sütunu ana tabloda mevcut olmalıdır - Genellikle primary key veya unique key olmalıdır - Foreign key ile aynı veri tipinde olmalıdır - Index'lenmiş olması performans için kritiktir
Uyarılar ¶
- Owner key değiştirilirse, foreign key ile uyumlu olduğundan emin olun - Non-unique owner key kullanımı veri tutarsızlığına yol açabilir - Migration'larda bu ilişkiyi doğru tanımladığınızdan emin olun
Döndürür:
- Yapılandırılmış HasOneField pointer'ı (method chaining için)
func (*HasOneField) Query ¶
func (h *HasOneField) Query(fn func(interface{}) interface{}) *HasOneField
Query, ilişki sorgusunu özelleştirmek için callback fonksiyonu ayarlar.
Bu method, ilişkili kayıtlar yüklenirken uygulanacak özel sorgu koşullarını tanımlamanızı sağlar. Filtreleme, sıralama, eager loading gibi işlemler için kullanılır.
Parametreler ¶
- **fn**: Sorgu callback fonksiyonu - GORM query nesnesini alır ve değiştirilmiş query döndürür
Kullanım Senaryoları ¶
- **Filtreleme**: Sadece aktif kayıtları yükleme - **Sıralama**: İlişkili kayıtları belirli bir sıraya göre getirme - **Eager Loading**: İlişkili kayıtların alt ilişkilerini de yükleme - **Soft Delete**: Silinmiş kayıtları dahil etme veya hariç tutma - **Performans**: Select ile sadece gerekli sütunları çekme
Kullanım Örnekleri ¶
// Sadece aktif profilleri yükle
field := fields.HasOne("Profile", "profile", "profiles").
Query(func(q interface{}) interface{} {
return q.(*gorm.DB).Where("status = ?", "active")
})
// Profili ülke bilgisi ile birlikte yükle
field := fields.HasOne("Profile", "profile", "profiles").
Query(func(q interface{}) interface{} {
return q.(*gorm.DB).Preload("Country")
})
// Sadece belirli sütunları çek (performans optimizasyonu)
field := fields.HasOne("Profile", "profile", "profiles").
Query(func(q interface{}) interface{} {
return q.(*gorm.DB).Select("id", "full_name", "avatar")
})
// Sıralama ekle
field := fields.HasOne("Invoice", "invoice", "invoices").
Query(func(q interface{}) interface{} {
return q.(*gorm.DB).Order("created_at DESC")
})
// Birden fazla koşul
field := fields.HasOne("Profile", "profile", "profiles").
Query(func(q interface{}) interface{} {
db := q.(*gorm.DB)
return db.Where("verified = ?", true).
Where("status = ?", "active").
Order("updated_at DESC")
})
GORM Entegrasyonu ¶
Callback fonksiyonu, GORM'un *gorm.DB tipini alır ve değiştirir:
func(q interface{}) interface{} {
db := q.(*gorm.DB)
// GORM query chain'i burada
return db.Where(...).Order(...)
}
Önemli Notlar ¶
- Callback fonksiyonu her ilişki yüklemesinde çalışır - Type assertion kullanırken dikkatli olun (panic riski) - Performans için sadece gerekli sütunları Select ile çekin - N+1 sorgu problemini önlemek için Preload kullanın
Performans İpuçları ¶
- **Select**: Sadece gerekli sütunları çekin - **Index**: Where koşullarında kullanılan sütunları index'leyin - **Preload**: Alt ilişkileri tek sorguda yükleyin - **Omit**: Gereksiz büyük sütunları (BLOB, TEXT) hariç tutun
Uyarılar ¶
- Callback içinde panic oluşursa uygulama çökebilir - Type assertion başarısız olursa runtime error oluşur - Karmaşık sorgular performansı etkileyebilir - Callback'te yapılan değişiklikler tüm yüklemeleri etkiler
Döndürür:
- Yapılandırılmış HasOneField pointer'ı (method chaining için)
func (*HasOneField) ResolveHoverCard ¶
func (h *HasOneField) ResolveHoverCard(resolver HoverCardResolver) *HasOneField
ResolveHoverCard, hover card verilerini çözmek için callback fonksiyonunu ayarlar.
Bu metod, hover card açıldığında çağrılacak resolver fonksiyonunu belirler. Resolver, ilişkili kaydın hover card verilerini döndürür.
Parametreler ¶
- **resolver**: Hover card resolver callback fonksiyonu
Kullanım Örneği ¶
field := fields.HasOne("Profile", "profile", "profiles").
ForeignKey("user_id").
HoverCard(&ProfileHoverCard{}).
ResolveHoverCard(func(ctx context.Context, record interface{}, relatedID interface{}, field fields.Field) (interface{}, error) {
// İlişkili kaydı veritabanından al
profile := &Profile{}
if err := db.First(profile, relatedID).Error; err != nil {
return nil, err
}
// Hover card verisini döndür
return &ProfileHoverCard{
Avatar: profile.Avatar,
Bio: profile.Bio,
Location: profile.Location,
}, nil
})
API Endpoint ¶
Frontend, hover card açıldığında şu endpoint'e istek atar:
GET /api/resource/{resource}/resolver/{field_name}?id={related_id}
POST /api/resource/{resource}/resolver/{field_name} (body: {id: related_id})
Döndürür:
- HasOneField pointer'ı (method chaining için)
func (*HasOneField) ResolveRelationship ¶
func (h *HasOneField) ResolveRelationship(item interface{}) (interface{}, error)
ResolveRelationship, ilişkiyi çözerek ilişkili kaydı yükler.
Bu method, HasOne ilişkisinde tek bir ilişkili kaydı veritabanından yükler. Gerçek implementasyonda, bu method veritabanı sorgusunu çalıştırır ve ilişkili resource'u döndürür.
Çalışma Mantığı ¶
1. Item parametresini kontrol eder (nil kontrolü) 2. Item'dan owner key değerini çıkarır (örn. user.ID) 3. İlişkili tabloda foreign key ile sorgu yapar 4. Tek bir ilişkili kaydı bulur ve döndürür 5. Hata durumunda error döndürür
Parametreler ¶
- **item**: Ana kayıt (owner record) - ilişkinin sahibi olan kayıt
Dönüş Değerleri ¶
- **interface{}**: İlişkili kayıt (tek bir record) veya nil - **error**: Hata durumunda error, başarılı ise nil
Kullanım Senaryoları ¶
- **Lazy Loading**: İlişkili kaydı isteğe bağlı yükleme - **Dynamic Resolution**: Runtime'da ilişki çözümleme - **API Endpoints**: İlişkili veriyi ayrı endpoint'te sunma - **Conditional Loading**: Belirli koşullarda ilişki yükleme - **Manual Preloading**: Özel preload stratejileri
Kullanım Örneği (Teorik) ¶
// Field tanımı
field := fields.HasOne("Profile", "profile", "profiles").
ForeignKey("user_id").
OwnerKey("id")
// Ana kayıt
user := User{ID: 1, Name: "John"}
// İlişkiyi çözümle
profile, err := field.ResolveRelationship(user)
if err != nil {
log.Fatal(err)
}
// Sonuç
fmt.Printf("Profile: %+v\n", profile)
// Output: Profile: &Profile{ID: 42, UserID: 1, FullName: "John Doe"}
Gerçek Implementasyon (Örnek) ¶
func (h *HasOneField) ResolveRelationship(item interface{}) (interface{}, error) {
if item == nil {
return nil, nil
}
// Owner key değerini çıkar
ownerValue := extractFieldValue(item, h.OwnerKeyColumn)
if ownerValue == nil {
return nil, nil
}
// İlişkili resource'u bul
relatedResource := resourceRegistry.Get(h.RelatedResourceSlug)
if relatedResource == nil {
return nil, fmt.Errorf("related resource not found: %s", h.RelatedResourceSlug)
}
// Veritabanı sorgusu
var result interface{}
query := db.Model(relatedResource.Model()).
Where(fmt.Sprintf("%s = ?", h.ForeignKeyColumn), ownerValue)
// Query callback uygula
if h.QueryCallback != nil {
query = h.QueryCallback(query).(*gorm.DB)
}
// Tek kayıt bul
err := query.First(&result).Error
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil // İlişkili kayıt yok
}
return nil, err
}
return result, nil
}
SQL Sorgusu ¶
Method, aşağıdaki gibi bir SQL sorgusu oluşturur:
SELECT * FROM profiles WHERE user_id = 1 LIMIT 1
Hata Durumları ¶
**Nil Item:** - Input: nil - Output: (nil, nil)
**Kayıt Bulunamadı:** - Input: User{ID: 999} - Output: (nil, nil) // Error değil, sadece nil
**Veritabanı Hatası:** - Input: User{ID: 1} - Output: (nil, error) // Bağlantı hatası, syntax error vb.
**Birden Fazla Kayıt:** - Input: User{ID: 1} - Output: İlk kaydı döndürür (LIMIT 1)
Performans Optimizasyonu ¶
**Select Specific Columns:**
field.Query(func(q interface{}) interface{} {
return q.(*gorm.DB).Select("id", "full_name", "avatar")
})
**Index Kullanımı:**
CREATE INDEX idx_profiles_user_id ON profiles(user_id);
**Cache Stratejisi:**
// Cache'den kontrol et
if cached := cache.Get(cacheKey); cached != nil {
return cached, nil
}
// Veritabanından yükle
result, err := field.ResolveRelationship(item)
if err == nil && result != nil {
cache.Set(cacheKey, result, 5*time.Minute)
}
Eager Loading vs Lazy Loading ¶
**Lazy Loading (Bu Method):** - Her kayıt için ayrı sorgu - N+1 problem riski - İsteğe bağlı yükleme
**Eager Loading (Preload):** - Tek sorguda tüm ilişkiler - Performanslı - Toplu yükleme
Önemli Notlar ¶
- Şu anki implementasyon placeholder'dır (nil, nil döndürür) - Gerçek implementasyon veritabanı erişimi gerektirir - Query callback uygulanmalıdır - Error handling kritiktir - Nil item güvenli şekilde işlenir
Best Practices ¶
- Eager loading tercih edin (liste görünümlerinde) - Lazy loading sadece gerektiğinde kullanın - Query callback ile filtreleme yapın - Index'leri doğru tanımlayın - Cache mekanizması kullanın - Error'ları loglamayı unutmayın
Uyarılar ¶
- N+1 sorgu problemine dikkat edin - Nil pointer dereference riskine karşı kontrol yapın - Veritabanı bağlantı havuzunu yönetin - Timeout ayarlarını yapılandırın - Transaction içinde çalışırken dikkatli olun
Döndürür:
- İlişkili kayıt (interface{}) veya nil
- Hata durumunda error, başarılı ise nil
func (*HasOneField) Searchable ¶
func (h *HasOneField) Searchable() Element
Searchable, alanı aranabilir olarak işaretler (Element interface'ini implement eder).
Bu method, HasOne ilişkisini global search (genel arama) özelliğine dahil eder. Global search, kullanıcıların tüm kayıtlar arasında arama yapmasını sağlar.
Çalışma Mantığı ¶
Method, GlobalSearch field'ını true olarak ayarlar ve Element interface'ini döndürür. Bu, field'ın global search sorgularına dahil edilmesini sağlar.
Dönüş Değeri ¶
- Element interface'i (method chaining için)
Kullanım Senaryoları ¶
- **Global Search**: Tüm kayıtlarda arama yapılabilir hale getirme - **Quick Search**: Hızlı arama özelliğine dahil etme - **Search Bar**: Arama çubuğunda ilişki araması - **Filter Integration**: Filtreleme sistemine entegrasyon - **Admin Panel**: Yönetim panelinde arama özelliği
Kullanım Örneği ¶
// Searchable HasOne field
field := fields.HasOne("Profile", "profile", "profiles").
Searchable()
// Method chaining ile diğer özellikler
field := fields.HasOne("Profile", "profile", "profiles").
Searchable().
WithEagerLoad().
ForeignKey("user_id")
Global Search Davranışı ¶
HasOne ilişkisi searchable olarak işaretlendiğinde:
**İlişki Varlığı Aranır:** - İlişkili kayıt var mı yok mu kontrol edilir - İlişkili kaydın ID'si aranabilir
**İlişkili Kayıt İçeriği Aranmaz:** - HasOne için ilişkili kaydın içeriği (örn. profile.full_name) aranmaz - Sadece ilişkinin varlığı aranabilir
HasOne vs HasMany Searchable Karşılaştırması ¶
**HasOne (Bu Method):**
field := fields.HasOne("Profile", "profile", "profiles").
Searchable()
// İlişki varlığı aranır (profile var mı?)
**HasMany:**
field := fields.HasMany("Posts", "posts", "posts").
Searchable().
SearchableColumns("title", "body")
// İlişkili kayıtların içeriği aranır (post title, body)
Search Query Implementation (Örnek) ¶
func buildSearchQuery(fields []Field, searchTerm string) *gorm.DB {
query := db.Model(&User{})
for _, field := range fields {
if !field.IsSearchable() {
continue
}
if hasOneField, ok := field.(*HasOneField); ok {
// HasOne için ilişki varlığı kontrolü
query = query.Or(
db.Joins(hasOneField.Key).
Where(fmt.Sprintf("%s.id IS NOT NULL", hasOneField.Key)),
)
}
}
return query
}
Frontend Integration ¶
Frontend'de searchable field'lar otomatik olarak arama formuna eklenir:
// API Response
{
"fields": [
{
"name": "Profile",
"key": "profile",
"type": "relationship",
"searchable": true // Bu method ile ayarlanır
}
]
}
// Frontend Search Form
<SearchBar>
<input placeholder="Search users with profile..." />
</SearchBar>
Element Interface Implementation ¶
Bu method, Element interface'ini implement eder:
type Element interface {
Searchable() Element
IsSearchable() bool
// ... diğer method'lar
}
IsSearchable Kontrolü ¶
Searchable olup olmadığını kontrol etmek için:
if field.GlobalSearch {
// Field searchable
includeInSearch(field)
}
Kullanım Örnekleri ¶
**Basit Kullanım:**
field := fields.HasOne("Profile", "profile", "profiles").
Searchable()
**Diğer Özelliklerle Birlikte:**
field := fields.HasOne("Profile", "profile", "profiles").
Searchable().
WithEagerLoad().
ForeignKey("user_id").
Required()
**Koşullu Searchable:**
field := fields.HasOne("Profile", "profile", "profiles")
if config.EnableProfileSearch {
field.Searchable()
}
Search Query Örnekleri ¶
**İlişki Varlığı Araması:**
// Profili olan kullanıcıları bul
db.Joins("Profile").
Where("profiles.id IS NOT NULL").
Find(&users)
**İlişki Yokluğu Araması:**
// Profili olmayan kullanıcıları bul
db.Joins("LEFT JOIN profiles ON profiles.user_id = users.id").
Where("profiles.id IS NULL").
Find(&users)
Performans Considerations ¶
**Index Kullanımı:**
CREATE INDEX idx_profiles_user_id ON profiles(user_id);
**Join Optimizasyonu:**
// Efficient join
db.Joins("Profile").Find(&users)
// Inefficient (N+1)
for _, user := range users {
db.Model(&user).Association("Profile").Find(&user.Profile)
}
Önemli Notlar ¶
- GlobalSearch field'ı true olarak ayarlanır - Element interface'i döndürülür (method chaining için) - HasOne için sadece ilişki varlığı aranır, içerik aranmaz - Frontend'de otomatik olarak arama formuna eklenir - Search query'lerde JOIN kullanılır
Best Practices ¶
**Searchable Kullanımı:**
// İyi: İlişki varlığı önemli
field := fields.HasOne("Profile", "profile", "profiles").
Searchable() // Profili olan/olmayan kullanıcıları bul
// Kötü: İlişki içeriği aranmak isteniyorsa
// HasOne searchable ile içerik aranamaz
// İlişkili resource'da ayrı field'lar tanımlayın
**Index Tanımlama:**
// Migration'da index ekle CREATE INDEX idx_profiles_user_id ON profiles(user_id);
**Query Optimization:**
// Eager loading ile birlikte kullan
field := fields.HasOne("Profile", "profile", "profiles").
Searchable().
WithEagerLoad()
Alternatif Yaklaşımlar ¶
İlişkili kayıt içeriğinde arama yapmak için:
// Profile resource'da searchable field'lar tanımla
profileResource := resource.New("profiles").
Fields(
fields.Text("Full Name", "full_name").Searchable(),
fields.Text("Bio", "bio").Searchable(),
)
// User resource'da HasOne tanımla
userResource := resource.New("users").
Fields(
fields.HasOne("Profile", "profile", profileResource).
WithEagerLoad(),
)
Uyarılar ¶
- HasOne searchable ile sadece ilişki varlığı aranır - İlişkili kayıt içeriği aranmaz (full_name, bio vb.) - Search query'lerde JOIN kullanılır (performans etkisi) - Index'lerin doğru tanımlandığından emin olun - Büyük veri setlerinde performans test edin
Döndürür:
- Element interface'i (method chaining için)
func (*HasOneField) ValidateRelationship ¶
func (h *HasOneField) ValidateRelationship(value interface{}) error
ValidateRelationship, ilişkinin geçerliliğini doğrular.
Bu method, HasOne ilişkisinde en fazla bir ilişkili kaydın var olduğunu doğrular. Gerçek implementasyonda, veritabanı constraint'lerini ve iş kurallarını kontrol eder.
Çalışma Mantığı ¶
1. Value parametresini kontrol eder (nil, tip, format) 2. İlişkili kayıt sayısını kontrol eder (en fazla 1 olmalı) 3. Foreign key constraint'lerini doğrular 4. İş kurallarını uygular (required, unique, vb.) 5. Hata durumunda error döndürür
Parametreler ¶
- **value**: Doğrulanacak değer (genellikle ilişkili kaydın ID'si)
Dönüş Değeri ¶
- **error**: Validasyon hatası varsa error, geçerli ise nil
Kullanım Senaryoları ¶
- **Form Validation**: Kullanıcı input'unu doğrulama - **API Validation**: Request payload'unu kontrol etme - **Data Integrity**: Veri tutarlılığını sağlama - **Business Rules**: İş kurallarını uygulama - **Constraint Checking**: Veritabanı constraint'lerini kontrol etme
Kullanım Örneği (Teorik) ¶
field := fields.HasOne("Profile", "profile", "profiles").
ForeignKey("user_id").
Required()
// Validasyon
err := field.ValidateRelationship(profileID)
if err != nil {
return fmt.Errorf("validation failed: %w", err)
}
Gerçek Implementasyon (Örnek) ¶
func (h *HasOneField) ValidateRelationship(value interface{}) error {
// Nil kontrolü
if value == nil {
if h.IsRequired() {
return fmt.Errorf("%s is required", h.Name)
}
return nil
}
// Tip kontrolü
id, ok := value.(uint)
if !ok {
return fmt.Errorf("%s must be a valid ID", h.Name)
}
// ID geçerliliği
if id == 0 {
return fmt.Errorf("%s ID cannot be zero", h.Name)
}
// İlişkili kayıt var mı?
var count int64
err := db.Model(relatedModel).
Where("id = ?", id).
Count(&count).Error
if err != nil {
return fmt.Errorf("failed to validate %s: %w", h.Name, err)
}
if count == 0 {
return fmt.Errorf("%s with ID %d does not exist", h.Name, id)
}
// Birden fazla kayıt kontrolü (HasOne için)
if count > 1 {
return fmt.Errorf("%s has multiple records (expected one)", h.Name)
}
// Foreign key constraint kontrolü
if h.ForeignKeyColumn != "" {
// Foreign key'in başka bir kayıt tarafından kullanılıp kullanılmadığını kontrol et
var existingCount int64
err := db.Model(relatedModel).
Where(fmt.Sprintf("%s = ?", h.ForeignKeyColumn), ownerID).
Where("id != ?", id).
Count(&existingCount).Error
if err != nil {
return err
}
if existingCount > 0 {
return fmt.Errorf("%s already has a related record", h.Name)
}
}
return nil
}
Validasyon Kuralları ¶
**Required Kontrolü:**
if value == nil && field.IsRequired() {
return errors.New("field is required")
}
**Tip Kontrolü:**
if _, ok := value.(uint); !ok {
return errors.New("invalid type")
}
**Existence Kontrolü:**
var count int64
db.Model(&Profile{}).Where("id = ?", value).Count(&count)
if count == 0 {
return errors.New("record not found")
}
**Uniqueness Kontrolü:**
var count int64
db.Model(&Profile{}).Where("user_id = ?", userID).Count(&count)
if count > 1 {
return errors.New("multiple records found")
}
Hata Mesajları ¶
**Required Error:** - "Profile is required" - "Profile cannot be empty"
**Type Error:** - "Profile must be a valid ID" - "Profile has invalid type"
**Not Found Error:** - "Profile with ID 42 does not exist" - "Profile not found"
**Duplicate Error:** - "Profile already exists for this user" - "User already has a profile"
Custom Validation ¶
Özel validasyon kuralları eklenebilir:
field := fields.HasOne("Profile", "profile", "profiles").
Validate(func(value interface{}) error {
id := value.(uint)
// Özel validasyon mantığı
if id < 100 {
return errors.New("profile ID must be >= 100")
}
return nil
})
Veritabanı Constraint'leri ¶
**Foreign Key Constraint:**
ALTER TABLE profiles ADD CONSTRAINT fk_profiles_user_id FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
**Unique Constraint:**
ALTER TABLE profiles ADD CONSTRAINT uk_profiles_user_id UNIQUE (user_id);
Performans Optimizasyonu ¶
**Cache Kullanımı:**
// Validation sonuçlarını cache'le
cacheKey := fmt.Sprintf("validation:%s:%v", h.Key, value)
if cached := cache.Get(cacheKey); cached != nil {
return cached.(error)
}
**Batch Validation:**
// Birden fazla değeri tek sorguda doğrula
ids := []uint{1, 2, 3}
var count int64
db.Model(&Profile{}).Where("id IN ?", ids).Count(&count)
Önemli Notlar ¶
- Şu anki implementasyon placeholder'dır (nil döndürür) - Gerçek implementasyon veritabanı erişimi gerektirir - Validasyon kuralları field konfigürasyonuna bağlıdır - Error mesajları kullanıcı dostu olmalıdır - Performans için cache kullanılabilir
Best Practices ¶
- Validasyon kurallarını açık ve anlaşılır yapın - Error mesajlarını kullanıcı dostu yazın - Veritabanı constraint'lerini kullanın - Validasyonu hem client hem server tarafında yapın - Batch validation ile performansı artırın
Uyarılar ¶
- Validasyon atlanmamalıdır (güvenlik riski) - Error mesajları hassas bilgi içermemelidir - Veritabanı hatalarını yakalayın ve loglamayı unutmayın - Race condition'lara dikkat edin (concurrent updates) - Transaction içinde validasyon yapın
Döndürür:
- Validasyon hatası varsa error, geçerli ise nil
func (*HasOneField) WithEagerLoad ¶
func (h *HasOneField) WithEagerLoad() *HasOneField
WithEagerLoad, yükleme stratejisini eager loading olarak ayarlar.
Eager loading, ilişkili kayıtların ana kayıtlarla birlikte tek sorguda yüklenmesini sağlar. Bu, N+1 sorgu problemini önler ve performansı önemli ölçüde artırır.
Eager Loading Nedir? ¶
Eager loading, ilişkili verilerin önceden (eager) yüklenmesi anlamına gelir. Ana kayıtlar sorgulanırken, ilişkili kayıtlar da aynı anda JOIN veya ayrı bir sorgu ile yüklenir ve cache'lenir.
Kullanım Senaryoları ¶
- **Liste Görünümleri**: Birden fazla kaydın ilişkileriyle birlikte gösterilmesi - **API Responses**: İlişkili verilerin tek response'da dönülmesi - **Raporlama**: Toplu veri çekimlerinde performans optimizasyonu - **Dashboard**: Özet bilgilerin hızlı yüklenmesi - **Export İşlemleri**: Büyük veri setlerinin verimli işlenmesi
Kullanım Örneği ¶
// Eager loading ile (önerilen)
field := fields.HasOne("Profile", "profile", "profiles").
WithEagerLoad()
// Kullanıcıları profilleriyle birlikte yükle
// SQL: SELECT * FROM users; SELECT * FROM profiles WHERE user_id IN (1,2,3,...)
users := []User{}
db.Preload("Profile").Find(&users)
Performans Karşılaştırması ¶
**Lazy Loading (N+1 Problem):**
// 1 sorgu: Kullanıcıları getir
users := []User{} // 100 kullanıcı
db.Find(&users)
// 100 sorgu: Her kullanıcı için profil getir
for _, user := range users {
db.Model(&user).Association("Profile").Find(&user.Profile)
}
// Toplam: 101 sorgu
**Eager Loading:**
// 2 sorgu: Kullanıcıları ve tüm profilleri getir
users := []User{}
db.Preload("Profile").Find(&users)
// Toplam: 2 sorgu (veya JOIN ile 1 sorgu)
GORM Entegrasyonu ¶
Eager loading, GORM'un Preload fonksiyonu ile çalışır:
db.Preload("Profile").Find(&users)
db.Preload("Profile.Country").Find(&users) // İç içe ilişkiler
Avantajlar ¶
- **Performans**: N+1 sorgu problemini önler - **Hız**: Tek seferde tüm veriler yüklenir - **Verimlilik**: Veritabanı bağlantı sayısını azaltır - **Öngörülebilirlik**: Sorgu sayısı sabittir - **Cache Dostu**: Tüm veriler bellekte hazır
Dezavantajlar ¶
- **Bellek Kullanımı**: Tüm ilişkili veriler belleğe yüklenir - **Gereksiz Veri**: Kullanılmayacak veriler de yüklenebilir - **İlk Yükleme**: İlk sorgu daha yavaş olabilir - **Karmaşık Sorgular**: Çok sayıda ilişki JOIN karmaşıklığı artırır
Ne Zaman Kullanılmalı? ¶
**Eager Loading Kullan:** - Liste görünümlerinde (index, table) - İlişkili veri kesinlikle gerekli olduğunda - Birden fazla kayıt işlenirken - API response'larında - Export/raporlama işlemlerinde
**Lazy Loading Kullan:** - Tek kayıt görünümlerinde (show, detail) - İlişkili veri nadiren gerekli olduğunda - Bellek kısıtlı ortamlarda - Çok büyük ilişkili veri setlerinde
Önemli Notlar ¶
- Varsayılan strateji EAGER_LOADING'dir (N+1 problemini önlemek için) - Çok sayıda ilişki için selective preloading kullanın - İç içe ilişkiler için nokta notasyonu kullanın: "Profile.Country" - Conditional preloading için Query callback kullanın
İleri Seviye Kullanım ¶
// Koşullu eager loading
field := fields.HasOne("Profile", "profile", "profiles").
WithEagerLoad().
Query(func(q interface{}) interface{} {
return q.(*gorm.DB).Where("verified = ?", true)
})
// İç içe ilişkiler
db.Preload("Profile.Country").
Preload("Profile.Avatar").
Find(&users)
Döndürür:
- Yapılandırılmış HasOneField pointer'ı (method chaining için)
func (*HasOneField) WithHoverCard ¶
func (h *HasOneField) WithHoverCard(config HoverCardConfig) *HasOneField
WithHoverCard, hover card konfigürasyonunu ayarlar.
Bu metod, index ve detail sayfalarında ilişkili kaydın hover card ile nasıl görüntüleneceğini belirler.
Parametreler ¶
- **config**: Hover card konfigürasyonu
Kullanım Örneği (Deprecated - Yeni API kullanın) ¶
field := fields.HasOne("Profile", "profile", "profiles").
WithHoverCard(*fields.NewHoverCardConfig())
Yeni API (Önerilen) ¶
field := fields.HasOne("Profile", "profile", "profiles").
HoverCard(&ProfileHoverCard{}).
ResolveHoverCard(func(ctx context.Context, record interface{}, relatedID interface{}, field fields.Field) (interface{}, error) {
// Custom logic
return &ProfileHoverCard{...}, nil
})
Döndürür:
- HasOneField pointer'ı (method chaining için)
func (*HasOneField) WithLazyLoad ¶
func (h *HasOneField) WithLazyLoad() *HasOneField
WithLazyLoad, yükleme stratejisini lazy loading olarak ayarlar.
Lazy loading, ilişkili kayıtların sadece gerektiğinde (on-demand) yüklenmesini sağlar. Bu, ilk sorgu performansını artırır ancak N+1 sorgu problemine yol açabilir.
Lazy Loading Nedir? ¶
Lazy loading, ilişkili verilerin geç (lazy) yüklenmesi anlamına gelir. Ana kayıtlar sorgulanırken ilişkili kayıtlar yüklenmez, sadece ilişkiye erişildiğinde ayrı bir sorgu ile yüklenir.
Kullanım Senaryoları ¶
- **Detay Görünümleri**: Tek kaydın detaylı gösteriminde - **Koşullu Yükleme**: İlişkili veri sadece belirli durumlarda gerekli - **Bellek Optimizasyonu**: Büyük ilişkili veri setlerinde - **API Pagination**: Sayfalanmış sonuçlarda gereksiz veri yüklemesini önleme - **Selective Loading**: Kullanıcı tercihine göre veri yükleme
Kullanım Örneği ¶
// Lazy loading ile
field := fields.HasOne("Profile", "profile", "profiles").
WithLazyLoad()
// Kullanıcıyı yükle (profil yüklenmez)
user := User{}
db.First(&user, 1)
// Profil sadece erişildiğinde yüklenir
db.Model(&user).Association("Profile").Find(&user.Profile)
N+1 Sorgu Problemi ¶
Lazy loading'in en büyük dezavantajı N+1 sorgu problemidir:
// 1 sorgu: 100 kullanıcı getir
users := []User{}
db.Find(&users)
// 100 sorgu: Her kullanıcı için ayrı profil sorgusu
for _, user := range users {
db.Model(&user).Association("Profile").Find(&user.Profile)
// Her iterasyonda yeni bir sorgu!
}
// Toplam: 101 sorgu (çok yavaş!)
Performans Karşılaştırması ¶
**Lazy Loading:** - İlk yükleme: Hızlı (sadece ana kayıtlar) - İlişki erişimi: Yavaş (her erişimde yeni sorgu) - Toplam sorgu: N+1 (N = kayıt sayısı) - Bellek: Az (sadece gerekli veriler)
**Eager Loading:** - İlk yükleme: Yavaş (tüm veriler) - İlişki erişimi: Hızlı (zaten yüklü) - Toplam sorgu: 1-2 (sabit) - Bellek: Fazla (tüm veriler)
Avantajlar ¶
- **İlk Yükleme Hızı**: Ana kayıtlar hızlı yüklenir - **Bellek Verimliliği**: Sadece gerekli veriler yüklenir - **Esneklik**: İlişki isteğe bağlı yüklenir - **Basitlik**: Otomatik çalışır, ekstra kod gerekmez - **Koşullu Yükleme**: Sadece gerektiğinde yükleme
Dezavantajlar ¶
- **N+1 Problem**: Çok sayıda ek sorgu oluşur - **Performans**: Liste görünümlerinde çok yavaş - **Öngörülemezlik**: Sorgu sayısı değişkendir - **Veritabanı Yükü**: Çok sayıda bağlantı açılır - **Debugging**: Sorgu sayısını takip etmek zor
Ne Zaman Kullanılmalı? ¶
**Lazy Loading Kullan:** - Tek kayıt görünümlerinde (show, detail, edit) - İlişkili veri nadiren gerekli olduğunda - Çok büyük ilişkili veri setlerinde - Bellek kısıtlı ortamlarda - Koşullu veri yükleme senaryolarında
**Eager Loading Kullan:** - Liste görünümlerinde (index, table, grid) - İlişkili veri kesinlikle gerekli olduğunda - Birden fazla kayıt işlenirken - API response'larında - Export/raporlama işlemlerinde
N+1 Problemini Önleme ¶
Lazy loading kullanırken N+1 problemini önlemek için:
// 1. Manuel Preload kullan
db.Preload("Profile").Find(&users)
// 2. Batch loading kullan
db.Model(&users).Association("Profile").Find(&profiles)
// 3. Eager loading'e geç
field.WithEagerLoad()
Önemli Notlar ¶
- Liste görünümlerinde lazy loading kullanmayın (N+1 riski) - Tek kayıt görünümlerinde lazy loading tercih edilebilir - Production'da sorgu sayısını mutlaka monitor edin - GORM'un Debug() modu ile sorguları kontrol edin
İleri Seviye Kullanım ¶
// Koşullu lazy loading
field := fields.HasOne("Profile", "profile", "profiles").
WithLazyLoad()
// Runtime'da eager loading'e geç
if needsProfile {
db.Preload("Profile").Find(&users)
} else {
db.Find(&users)
}
Debugging İpuçları ¶
// Sorgu sayısını kontrol et db.Debug().Find(&users) // SQL loglarını gösterir // N+1 tespiti için // Her iterasyonda "SELECT * FROM profiles" görüyorsanız N+1 var!
Uyarılar ¶
- Production'da lazy loading kullanırken dikkatli olun - N+1 problemi ciddi performans sorunlarına yol açar - Büyük veri setlerinde veritabanını aşırı yükleyebilir - Liste görünümlerinde kesinlikle eager loading kullanın
Döndürür:
- Yapılandırılmış HasOneField pointer'ı (method chaining için)
type Hideable ¶
type Hideable struct {
// contains filtered or unexported fields
}
Hideable, alanların görünürlüğünü kontrol etmesini sağlayan bir mixin'dir.
Farklı bağlamlarda (index, detail, create, update) görünürlük ve özel gizleme callback'leri için yapılandırma sağlar.
Kullanım ¶
type PasswordField struct {
fields.Base
fields.Hideable
}
field := &PasswordField{}
field.SetShowOnIndex(false)
field.SetShowOnDetail(false)
field.SetShowOnCreate(true)
field.SetShowOnUpdate(true)
Daha fazla örnek için docs/Fields.md dosyasına bakın.
func (*Hideable) GetHideCallback ¶
GetHideCallback, gizleme callback fonksiyonunu döndürür. Hiçbir callback ayarlanmamışsa nil döndürür.
Döndürür:
- Gizleme callback fonksiyonu veya ayarlanmamışsa nil
func (*Hideable) IsHidden ¶
IsHidden, alanın gizli olup olmadığını döndürür.
Döndürür:
- Alan gizliyse true, değilse false
func (*Hideable) SetHidden ¶
SetHidden, alanın gizli olup olmadığını ayarlar.
Parametreler:
- hidden: Alanı gizlemek için true, göstermek için false
Örnek:
field.SetHidden(true)
func (*Hideable) SetHideCallback ¶
SetHideCallback, özel bir gizleme callback fonksiyonu ayarlar.
Callback, context'i alır ve alan gizlenmeli ise true, gösterilmeli ise false döndürmelidir.
Parametreler:
- cb: Alanın gizlenip gizlenmeyeceğini belirleyen fonksiyon
Örnek:
field.SetHideCallback(func(ctx *context.Context) bool {
user := ctx.User()
return user == nil || !user.IsAdmin
})
func (*Hideable) SetShowOnCreate ¶
SetShowOnCreate, alanın oluşturma formunda gösterilip gösterilmeyeceğini ayarlar.
func (*Hideable) SetShowOnDetail ¶
SetShowOnDetail, alanın detay görünümünde gösterilip gösterilmeyeceğini ayarlar.
func (*Hideable) SetShowOnIndex ¶
SetShowOnIndex, alanın liste görünümünde gösterilip gösterilmeyeceğini ayarlar.
func (*Hideable) SetShowOnUpdate ¶
SetShowOnUpdate, alanın güncelleme formunda gösterilip gösterilmeyeceğini ayarlar.
func (*Hideable) ShowOnCreate ¶
ShowOnCreate, alanın oluşturma formunda gösterilip gösterilmeyeceğini döner.
func (*Hideable) ShowOnDetail ¶
ShowOnDetail, alanın detay görünümünde gösterilip gösterilmeyeceğini döner.
func (*Hideable) ShowOnIndex ¶
ShowOnIndex, alanın liste görünümünde gösterilip gösterilmeyeceğini döner.
func (*Hideable) ShowOnUpdate ¶
ShowOnUpdate, alanın güncelleme formunda gösterilip gösterilmeyeceğini döner.
type HoverCardConfig ¶
type HoverCardConfig struct {
// Enabled, hover card'ın aktif olup olmadığını belirler
Enabled bool `json:"enabled"`
// Struct, hover card verisi için kullanılacak struct (tip bilgisi)
// Bu, JSON serialization için kullanılır
Struct interface{} `json:"-"`
// Resolver, hover card verilerini çözmek için callback fonksiyonu
Resolver HoverCardResolver `json:"-"`
// Width, hover card genişliği (örn. "sm", "md", "lg", "xl")
Width string `json:"width,omitempty"`
// OpenDelay, hover card açılma gecikmesi (ms)
OpenDelay int `json:"open_delay,omitempty"`
// CloseDelay, hover card kapanma gecikmesi (ms)
CloseDelay int `json:"close_delay,omitempty"`
}
HoverCardConfig, ilişki field'ları için hover card görüntüleme ayarlarını yönetir.
Bu yapı, hasOne, belongsTo ve morphTo field'larının index ve detail sayfalarında hover card ile nasıl görüntüleneceğini kontrol eder.
Özellikler ¶
- **Enabled**: Hover card'ın aktif olup olmadığını belirler - **Struct**: Hover card verisi için kullanılacak struct (tip bilgisi) - **Resolver**: Hover card verilerini çözmek için callback fonksiyonu - **Width**: Hover card genişliği (örn. "sm", "md", "lg", "xl") - **OpenDelay**: Hover card açılma gecikmesi (ms) - **CloseDelay**: Hover card kapanma gecikmesi (ms)
Kullanım Örneği ¶
// Hover card struct'ı tanımla
type AuthorHoverCard struct {
Avatar string `json:"avatar"`
Name string `json:"name"`
Email string `json:"email"`
Phone string `json:"phone"`
}
// Field'a hover card ekle
field := fields.BelongsTo("Author", "author_id", "authors").
DisplayUsing("name").
HoverCard(&AuthorHoverCard{}).
ResolveHoverCard(func(ctx context.Context, record interface{}, relatedID interface{}, field fields.Field) (interface{}, error) {
// İlişkili kaydı veritabanından al
author := &Author{}
db.First(author, relatedID)
// Hover card verisini döndür
return &AuthorHoverCard{
Avatar: author.Avatar,
Name: author.Name,
Email: author.Email,
Phone: author.Phone,
}, nil
})
API Endpoint ¶
Frontend, hover card açıldığında şu endpoint'e istek atar:
GET /api/resource/{resource}/resolver/{field_name}?id={related_id}
POST /api/resource/{resource}/resolver/{field_name} (body: {id: related_id})
Daha fazla bilgi için docs/Relationships.md dosyasına bakın.
func NewHoverCardConfig ¶
func NewHoverCardConfig() *HoverCardConfig
NewHoverCardConfig, varsayılan hover card konfigürasyonu oluşturur.
Bu fonksiyon, temel hover card ayarlarıyla bir konfigürasyon döndürür.
Varsayılan Değerler ¶
- **Enabled**: true - **Width**: "md" - **OpenDelay**: 200ms - **CloseDelay**: 300ms
Kullanım Örneği ¶
config := fields.NewHoverCardConfig()
Döndürür:
- Varsayılan HoverCardConfig pointer'ı
func (*HoverCardConfig) Disable ¶
func (h *HoverCardConfig) Disable() *HoverCardConfig
Disable, hover card'ı devre dışı bırakır.
Bu metod, hover card gösterimini tamamen kapatır.
Kullanım Örneği ¶
config := fields.NewHoverCardConfig() config.Disable()
Döndürür:
- HoverCardConfig pointer'ı (method chaining için)
func (*HoverCardConfig) SetDelays ¶
func (h *HoverCardConfig) SetDelays(openDelay, closeDelay int) *HoverCardConfig
SetDelays, hover card açılma ve kapanma gecikmelerini ayarlar.
Bu metod, hover card'ın açılma ve kapanma gecikmelerini belirler.
Parametreler ¶
- **openDelay**: Açılma gecikmesi (ms) - **closeDelay**: Kapanma gecikmesi (ms)
Kullanım Örneği ¶
config := fields.NewHoverCardConfig() config.SetDelays(300, 500)
Döndürür:
- HoverCardConfig pointer'ı (method chaining için)
func (*HoverCardConfig) SetResolver ¶
func (h *HoverCardConfig) SetResolver(resolver HoverCardResolver) *HoverCardConfig
SetResolver, hover card verilerini çözmek için callback fonksiyonunu ayarlar.
Bu metod, hover card verilerini almak için kullanılacak resolver'ı belirler.
Parametreler ¶
- **resolver**: Hover card resolver callback fonksiyonu
Kullanım Örneği ¶
config := fields.NewHoverCardConfig()
config.SetResolver(func(ctx context.Context, record interface{}, relatedID interface{}, field fields.Field) (interface{}, error) {
// Custom logic
return &AuthorHoverCard{...}, nil
})
Döndürür:
- HoverCardConfig pointer'ı (method chaining için)
func (*HoverCardConfig) SetStruct ¶
func (h *HoverCardConfig) SetStruct(s interface{}) *HoverCardConfig
SetStruct, hover card verisi için kullanılacak struct'ı ayarlar.
Bu metod, hover card verisi için tip bilgisini belirler.
Parametreler ¶
- **s**: Hover card struct'ı (örn. &AuthorHoverCard{})
Kullanım Örneği ¶
config := fields.NewHoverCardConfig()
config.SetStruct(&AuthorHoverCard{})
Döndürür:
- HoverCardConfig pointer'ı (method chaining için)
func (*HoverCardConfig) SetWidth ¶
func (h *HoverCardConfig) SetWidth(width string) *HoverCardConfig
SetWidth, hover card genişliğini ayarlar.
Bu metod, hover card'ın genişliğini belirler.
Parametreler ¶
- **width**: Genişlik değeri ("sm", "md", "lg", "xl")
Kullanım Örneği ¶
config := fields.NewHoverCardConfig()
config.SetWidth("lg")
Döndürür:
- HoverCardConfig pointer'ı (method chaining için)
type HoverCardResolver ¶
type HoverCardResolver func(ctx context.Context, record interface{}, relatedID interface{}, field RelationshipField) (interface{}, error)
HoverCardResolver, hover card verilerini çözmek için kullanılan callback fonksiyonu tipi.
Bu fonksiyon, hover card açıldığında çağrılır ve ilişkili kaydın hover card verilerini döndürür.
Parametreler ¶
- **ctx**: Context - **record**: Ana kayıt (örn. Post, Comment, vb.) - **relatedID**: İlişkili kaydın ID'si - **field**: Field instance
Döndürür ¶
- **interface{}**: Hover card verisi (struct veya map) - **error**: Hata (varsa)
Kullanım Örneği ¶
resolver := func(ctx context.Context, record interface{}, relatedID interface{}, field Field) (interface{}, error) {
// İlişkili kaydı veritabanından al
author := &Author{}
db.First(author, relatedID)
// Hover card verisini döndür
return &AuthorHoverCard{
Avatar: author.Avatar,
Name: author.Name,
Email: author.Email,
Phone: author.Phone,
}, nil
}
type LoadingStrategy ¶
type LoadingStrategy string
LoadingStrategy, ilişkilerin nasıl yükleneceğini tanımlar.
İki ana strateji vardır: - EAGER_LOADING: İlişkili verileri önceden yükler (N+1 sorgu problemini önler) - LAZY_LOADING: İlişkili verileri ihtiyaç anında yükler (bellek tasarrufu)
const ( // EAGER_LOADING, ilişkili verileri önceden yükler. // N+1 sorgu problemini önlemek için önerilir. EAGER_LOADING LoadingStrategy = "eager" // LAZY_LOADING, ilişkili verileri ihtiyaç anında yükler. // Bellek tasarrufu sağlar ancak N+1 sorgu problemine neden olabilir. LAZY_LOADING LoadingStrategy = "lazy" )
type MorphTo ¶
type MorphTo struct {
Schema
TypeMappings map[string]string // Type => Resource slug mapping
DisplayMappings map[string]string // Type => Display field name
QueryCallback func(query interface{}) interface{}
LoadingStrategy LoadingStrategy
GormRelationConfig *RelationshipGormConfig
// contains filtered or unexported fields
}
MorphTo, polimorfik ilişkiyi temsil eder (örn. Comment -> Commentable).
MorphTo ilişkisi, bir kaydın farklı tiplerdeki kayıtlara ait olabileceğini belirtir. Bu, veritabanında morph_type ve morph_id sütunları ile temsil edilir.
Kullanım Senaryoları ¶
- **Comment -> Commentable**: Bir yorum hem Post'a hem de Video'ya ait olabilir - **Image -> Imageable**: Bir resim hem User'a hem de Product'a ait olabilir - **Tag -> Taggable**: Bir etiket hem Post'a hem de Video'ya ait olabilir
Özellikler ¶
- **Tip Eşlemeleri**: Veritabanı tip değerleri ile resource slug'ları arasında eşleme - **Görüntüleme Eşlemeleri**: Her tip için görüntüleme alanı özelleştirme - **Eager/Lazy Loading**: Yükleme stratejisi seçimi - **GORM Yapılandırması**: Polimorfik sütunlar özelleştirme - **Hover Card**: Index ve detail sayfalarında hover card desteği
Kullanım Örneği ¶
field := fields.NewMorphTo("Commentable", "commentable").
Types(map[string]string{
"post": "posts",
"video": "videos",
}).
Displays(map[string]string{
"post": "title",
"video": "name",
}).
WithEagerLoad()
// Hover card ile
field := fields.NewMorphTo("Commentable", "commentable").
Types(map[string]string{
"post": "posts",
"video": "videos",
}).
WithHoverCard(fields.NewHoverCardConfig().
WithAvatar("thumbnail", "").
WithGrid([]fields.HoverCardGridField{
{Key: "title", Label: "Başlık", Type: "text"},
{Key: "created_at", Label: "Tarih", Type: "date"},
}, "2-column"))
Veritabanı Yapısı ¶
Polimorfik ilişki genellikle şu yapıya sahiptir:
CREATE TABLE comments (
id INT PRIMARY KEY,
commentable_type VARCHAR(255), -- "post" veya "video"
commentable_id INT, -- İlgili kaydın ID'si
content TEXT
);
Daha fazla bilgi için docs/Relationships.md dosyasına bakın.
func NewMorphTo ¶
NewMorphTo, yeni bir MorphTo polimorfik ilişki alanı oluşturur.
Bu fonksiyon, farklı tiplerdeki kayıtlara ait olabilen polimorfik ilişkiler için kullanılır. Veritabanında morph_type ve morph_id sütunları ile temsil edilir.
Parametreler ¶
- **name**: Alanın görünen adı (örn. "Commentable", "Imageable", "Taggable") - **key**: İlişki key'i (örn. "commentable", "imageable", "taggable")
Kullanım Örneği ¶
field := fields.NewMorphTo("Commentable", "commentable").
Types(map[string]string{
"post": "posts",
"video": "videos",
}).
Displays(map[string]string{
"post": "title",
"video": "name",
})
Varsayılan Değerler ¶
- **TypeMappings**: Boş map (Types() ile doldurulmalıdır) - **DisplayMappings**: Boş map (Displays() ile doldurulmalıdır) - **LoadingStrategy**: EAGER_LOADING (N+1 sorgu problemini önler) - **Polimorfik Sütunlar**: key + "_type" ve key + "_id" (örn. "commentable_type", "commentable_id")
Önemli Notlar ¶
- Types() metodu ile tip eşlemelerini tanımlamalısınız - Displays() metodu ile her tip için görüntüleme alanını belirtmelisiniz - Polimorfik sütunlar veritabanında mevcut olmalıdır
Döndürür:
- Yapılandırılmış MorphTo pointer'ı
Daha fazla bilgi için docs/Relationships.md dosyasına bakın.
func (*MorphTo) Displays ¶
Displays, her tip için görüntüleme alanını ayarlar.
Bu metod, her polimorfik tip için hangi alanın görüntüleneceğini belirler. Farklı tipler farklı görüntüleme alanlarına sahip olabilir.
Parametreler ¶
- **displays**: Tip değeri -> görüntüleme alanı eşlemesi (örn. {"post": "title", "video": "name"})
Kullanım Örneği ¶
field := fields.NewMorphTo("Commentable", "commentable").
Types(map[string]string{
"post": "posts",
"video": "videos",
}).
Displays(map[string]string{
"post": "title", // Post'lar için title alanı görüntülenir
"video": "name", // Video'lar için name alanı görüntülenir
})
Önemli Notlar ¶
- Her tip için görüntüleme alanı belirtilmelidir - Görüntüleme alanları, ilgili resource'larda mevcut olmalıdır - Frontend'de ilişkili kaydı gösterirken bu alanlar kullanılır
Döndürür:
- MorphTo pointer'ı (method chaining için)
func (*MorphTo) Extract ¶
func (m *MorphTo) Extract(resource interface{})
Extract, MorphTo'ya özgü veri çıkarma işlemini gerçekleştirir.
Bu metod, Schema.Extract'ı override eder çünkü MorphTo struct'ta doğrudan bir field'a sahip değildir. Bunun yerine, morph_type ve morph_id field'larından polimorfik ilişkiyi çözümler.
Parametreler ¶
- **resource**: Veri çıkarılacak kaynak
Önemli Notlar ¶
- Schema.Extract çağrılmaz çünkü MorphTo doğrudan bir field'a sahip değildir - ResolveRelationship kullanılarak polimorfik ilişki çözümlenir - Çözümlenen veriler m.Data'ya atanır
Kullanım Örneği ¶
field.Extract(comment)
// m.Data = {"type": "post", "id": 123, "morphToType": "post", "morphToId": 123}
func (*MorphTo) GetDisplayKey ¶
GetDisplayKey, görüntüleme key'ini döndürür.
MorphTo için kullanılmaz çünkü her tip farklı görüntüleme alanına sahip olabilir. Her zaman boş string döndürür.
Döndürür:
- Boş string (MorphTo için uygulanamaz)
func (*MorphTo) GetHoverCard ¶
func (m *MorphTo) GetHoverCard() *HoverCardConfig
GetHoverCard, hover card konfigürasyonunu döndürür.
Bu metod, hover card konfigürasyonunu alır.
Döndürür:
- HoverCardConfig pointer'ı (nil olabilir)
func (*MorphTo) GetLoadingStrategy ¶
func (m *MorphTo) GetLoadingStrategy() LoadingStrategy
GetLoadingStrategy, yükleme stratejisini döndürür.
Yükleme stratejisi tanımlanmışsa onu döndürür, aksi takdirde varsayılan EAGER_LOADING döndürür.
Döndürür:
- EAGER_LOADING veya LAZY_LOADING
func (*MorphTo) GetQueryCallback ¶
func (m *MorphTo) GetQueryCallback() func(interface{}) interface{}
GetQueryCallback, sorgu callback'ini döndürür.
Sorgu özelleştirme callback'i tanımlanmışsa onu döndürür, aksi takdirde varsayılan (no-op) callback döndürür.
Döndürür:
- Sorgu özelleştirme callback fonksiyonu
func (*MorphTo) GetRelatedResourceSlug ¶
GetRelatedResource, ilgili resource slug'ını döndürür.
MorphTo için uygulanamaz çünkü birden fazla resource'a ait olabilir. Her zaman boş string döndürür.
Döndürür:
- Boş string (MorphTo için uygulanamaz)
func (*MorphTo) GetRelationshipName ¶
GetRelationshipName, ilişkinin adını döndürür.
Döndürür:
- İlişkinin adı (örn. "Commentable", "Imageable")
func (*MorphTo) GetRelationshipType ¶
GetRelationshipType, ilişki türünü döndürür.
MorphTo için her zaman "morphTo" döndürür.
Döndürür:
- "morphTo" string değeri
func (*MorphTo) GetResourceForType ¶
GetResourceForType, verilen tip için resource slug'ını döndürür.
Bu metod, morph type değerine karşılık gelen resource slug'ını bulur. Tip kayıtlı değilse hata döndürür.
Parametreler ¶
- **morphType**: Morph type değeri (örn. "post", "video")
Kullanım Örneği ¶
resource, err := field.GetResourceForType("post")
// resource = "posts"
resource, err := field.GetResourceForType("unknown")
// err = "morph type 'unknown' is not registered"
Döndürür:
- Resource slug'ı (tip kayıtlıysa)
- Hata (tip kayıtlı değilse)
func (*MorphTo) GetSearchableColumns ¶
GetSearchableColumns, aranabilir sütunları döndürür.
MorphTo için kullanılmaz çünkü polimorfik ilişkilerde doğrudan arama yapılmaz. Her zaman boş slice döndürür.
Döndürür:
- Boş string slice (MorphTo için uygulanamaz)
func (*MorphTo) GetTypes ¶
GetTypes, tip eşlemelerini döndürür.
Bu metod, polimorfik ilişki için tanımlanmış tüm tip eşlemelerini döndürür. Tip eşlemeleri, veritabanı tip değerleri ile resource slug'ları arasındaki ilişkiyi belirtir.
Döndürür:
- Tip değeri -> resource slug eşlemesi (örn. {"post": "posts", "video": "videos"})
- Boş map (tip eşlemeleri tanımlanmamışsa)
func (*MorphTo) HoverCard ¶
HoverCard, hover card struct'ını ayarlar ve hover card'ı etkinleştirir.
Bu metod, hover card için kullanılacak struct'ı belirler ve hover card özelliğini aktif eder.
Parametreler ¶
- **hoverStruct**: Hover card verisi için kullanılacak struct (örn. &CommentableHoverCard{})
Kullanım Örneği ¶
type CommentableHoverCard struct {
Thumbnail string `json:"thumbnail"`
Title string `json:"title"`
Type string `json:"type"`
}
field := fields.NewMorphTo("Commentable", "commentable").
Types(map[string]string{
"post": "posts",
"video": "videos",
}).
HoverCard(&CommentableHoverCard{})
Döndürür:
- MorphTo pointer'ı (method chaining için)
func (*MorphTo) IsRequired ¶
IsRequired, alanın zorunlu olup olmadığını döndürür.
Döndürür:
- true ise alan zorunludur
func (*MorphTo) Query ¶
Query, ilişki sorgusunu özelleştirmek için callback ayarlar.
Bu metod, polimorfik ilişki sorgularını özelleştirmek için kullanılır. Filtreleme, sıralama veya diğer sorgu modifikasyonları yapılabilir.
Parametreler ¶
- **fn**: Sorgu özelleştirme callback fonksiyonu
Kullanım Örneği ¶
field := fields.NewMorphTo("Commentable", "commentable").
Query(func(q interface{}) interface{} {
// Sadece aktif kayıtları getir
return q.(*gorm.DB).Where("status = ?", "active")
})
Döndürür:
- MorphTo pointer'ı (method chaining için)
func (*MorphTo) ResolveHoverCard ¶
func (m *MorphTo) ResolveHoverCard(resolver HoverCardResolver) *MorphTo
ResolveHoverCard, hover card verilerini çözmek için callback fonksiyonunu ayarlar.
Bu metod, hover card açıldığında çağrılacak resolver fonksiyonunu belirler. Resolver, ilişkili kaydın hover card verilerini döndürür.
Parametreler ¶
- **resolver**: Hover card resolver callback fonksiyonu
Kullanım Örneği ¶
field := fields.NewMorphTo("Commentable", "commentable").
Types(map[string]string{
"post": "posts",
"video": "videos",
}).
HoverCard(&CommentableHoverCard{}).
ResolveHoverCard(func(ctx context.Context, record interface{}, relatedID interface{}, field fields.Field) (interface{}, error) {
// MorphTo için tip bilgisini al
morphType := record.(*Comment).CommentableType
// Tip'e göre ilişkili kaydı al
var data interface{}
switch morphType {
case "post":
post := &Post{}
if err := db.First(post, relatedID).Error; err != nil {
return nil, err
}
data = post
case "video":
video := &Video{}
if err := db.First(video, relatedID).Error; err != nil {
return nil, err
}
data = video
}
// Hover card verisini döndür
return &CommentableHoverCard{
Thumbnail: data.Thumbnail,
Title: data.Title,
Type: morphType,
}, nil
})
API Endpoint ¶
Frontend, hover card açıldığında şu endpoint'e istek atar:
GET /api/resource/{resource}/resolver/{field_name}?id={related_id}&type={morph_type}
POST /api/resource/{resource}/resolver/{field_name} (body: {id: related_id, type: morph_type})
Döndürür:
- MorphTo pointer'ı (method chaining için)
func (*MorphTo) ResolveRelationship ¶
ResolveRelationship, polimorfik ilişkiyi morph type'a göre çözümler.
Bu metod, reflection kullanarak struct'tan morph_type ve morph_id değerlerini çıkarır. Farklı field adı varyasyonlarını (CamelCase, snake_case) destekler.
Parametreler ¶
- **item**: İlişkili verileri çözümlenecek kaynak
Döndürür ¶
Polimorfik ilişki bilgilerini içeren map:
- **type**: Morph type değeri (örn. "post", "video")
- **id**: Morph ID değeri (ilgili kaydın ID'si)
- **morphToType**: Morph type değeri (alias)
- **morphToId**: Morph ID değeri (alias)
Desteklenen Field Adları ¶
- Type için: "CommentableType", "Commentable_Type" - ID için: "CommentableID", "CommentableId", "Commentable_ID", "Commentable_Id"
Kullanım Örneği ¶
type Comment struct {
ID int
CommentableType string // "post" veya "video"
CommentableID int // İlgili kaydın ID'si
Content string
}
resolved, err := field.ResolveRelationship(comment)
// resolved = {"type": "post", "id": 123, "morphToType": "post", "morphToId": 123}
Döndürür:
- İlişki bilgileri map'i veya nil
- Hata (çözümleme başarısız olursa)
func (*MorphTo) Searchable ¶
Searchable, alanı aranabilir olarak işaretler.
Bu metod, alanın global arama işlemlerine dahil edilmesini sağlar. Element interface'ini implement eder.
Kullanım Örneği ¶
field := fields.NewMorphTo("Commentable", "commentable").
Searchable()
// Bu alan global arama işlemlerine dahil edilir
Döndürür:
- Element interface'i (method chaining için)
func (*MorphTo) Types ¶
Types, polimorfik ilişki için tip eşlemelerini ayarlar.
Bu metod, veritabanındaki tip değerleri ile resource slug'ları arasında eşleme oluşturur. Her tip değeri, hangi resource'a karşılık geldiğini belirtir.
Parametreler ¶
- **types**: Tip değeri -> resource slug eşlemesi (örn. {"post": "posts", "video": "videos"})
Kullanım Örneği ¶
field := fields.NewMorphTo("Commentable", "commentable").
Types(map[string]string{
"post": "posts",
"video": "videos",
"article": "articles",
})
// commentable_type = "post" ise posts resource'u kullanılır
// commentable_type = "video" ise videos resource'u kullanılır
Önemli Notlar ¶
- Tip değerleri veritabanında commentable_type sütununda saklanır - Resource slug'ları, ilgili resource'ların benzersiz tanımlayıcılarıdır - Tüm olası tip değerleri bu map'te tanımlanmalıdır - Frontend'de select dropdown olarak görüntülenir
Döndürür:
- MorphTo pointer'ı (method chaining için)
func (*MorphTo) ValidateRelationship ¶
ValidateRelationship, ilişkiyi doğrular.
Bu metod, polimorfik ilişkinin geçerli olup olmadığını kontrol eder. Gerçek implementasyonda, morph type'ın tip eşlemelerinde kayıtlı olup olmadığını kontrol eder.
Parametreler ¶
- **value**: Doğrulanacak değer
Döndürür ¶
- Hata (doğrulama başarısız olursa)
Önemli Notlar ¶
- Morph type, TypeMappings'te tanımlanmış olmalıdır - Gerçek implementasyonda veritabanı kısıtlamaları kontrol edilir
func (*MorphTo) WithEagerLoad ¶
WithEagerLoad, yükleme stratejisini eager loading olarak ayarlar.
Eager loading, ilişkili verileri önceden yükler ve N+1 sorgu problemini önler. Polimorfik ilişkiler için önerilir.
Kullanım Örneği ¶
field := fields.NewMorphTo("Commentable", "commentable").
WithEagerLoad()
// İlişkili veriler önceden yüklenir
Döndürür:
- MorphTo pointer'ı (method chaining için)
func (*MorphTo) WithHoverCard ¶
func (m *MorphTo) WithHoverCard(config HoverCardConfig) *MorphTo
WithHoverCard, hover card konfigürasyonunu ayarlar.
Bu metod, index ve detail sayfalarında ilişkili kaydın hover card ile nasıl görüntüleneceğini belirler.
Parametreler ¶
- **config**: Hover card konfigürasyonu
Kullanım Örneği (Deprecated - Yeni API kullanın) ¶
field := fields.NewMorphTo("Commentable", "commentable").
WithHoverCard(*fields.NewHoverCardConfig())
Yeni API (Önerilen) ¶
field := fields.NewMorphTo("Commentable", "commentable").
HoverCard(&CommentableHoverCard{}).
ResolveHoverCard(func(ctx context.Context, record interface{}, relatedID interface{}, field fields.Field) (interface{}, error) {
// Custom logic
return &CommentableHoverCard{...}, nil
})
Döndürür:
- MorphTo pointer'ı (method chaining için)
func (*MorphTo) WithLazyLoad ¶
WithLazyLoad, yükleme stratejisini lazy loading olarak ayarlar.
Lazy loading, ilişkili verileri ihtiyaç anında yükler. Bellek tasarrufu sağlar ancak N+1 sorgu problemine neden olabilir.
Kullanım Örneği ¶
field := fields.NewMorphTo("Commentable", "commentable").
WithLazyLoad()
// İlişkili veriler ihtiyaç anında yüklenir
Döndürür:
- MorphTo pointer'ı (method chaining için)
type MorphToMany ¶
type MorphToMany struct {
Schema
TypeMappings map[string]string // Type => Resource slug mapping
DisplayMappings map[string]string // Type => Display field name
PivotTableName string // Pivot tablo adı
ForeignKeyColumn string // Ana tablonun FK (örn. "tag_id")
RelatedKeyColumn string // Polimorfik ID sütunu (örn. "taggable_id")
MorphTypeColumn string // Polimorfik tip sütunu (örn. "taggable_type")
QueryCallback func(query interface{}) interface{}
LoadingStrategy LoadingStrategy
GormRelationConfig *RelationshipGormConfig
}
MorphToMany, polimorfik many-to-many ilişkiyi temsil eder (örn. Tag -> Taggable: posts, videos).
MorphToMany ilişkisi, bir kaydın farklı tiplerdeki birden fazla kayda ait olabileceğini belirtir. Bu, veritabanında polimorfik pivot tablo ile temsil edilir.
Kullanım Senaryoları ¶
- **Tag -> Taggable**: Bir etiket hem Post'lara hem de Video'lara ait olabilir - **Image -> Imageable**: Bir resim hem User'lara hem de Product'lara ait olabilir
Veritabanı Yapısı ¶
Polimorfik pivot tablo genellikle şu yapıya sahiptir:
CREATE TABLE taggables (
tag_id INT, -- Ana tablo FK
taggable_id INT, -- Polimorfik ID
taggable_type VARCHAR, -- Polimorfik tip ("post", "video")
PRIMARY KEY (tag_id, taggable_id, taggable_type)
);
Kullanım Örneği ¶
field := fields.NewMorphToMany("Taggable", "taggable").
Types(map[string]string{
"post": "posts",
"video": "videos",
}).
Displays(map[string]string{
"post": "title",
"video": "name",
}).
PivotTable("taggables").
AutoOptions("name").
WithEagerLoad()
func NewMorphToMany ¶
func NewMorphToMany(name, key string) *MorphToMany
NewMorphToMany, yeni bir MorphToMany polimorfik many-to-many ilişki alanı oluşturur.
Parametreler ¶
- **name**: Alanın görünen adı (örn. "Taggable", "Imageable") - **key**: İlişki key'i (örn. "taggable", "imageable")
Varsayılan Değerler ¶
- **PivotTableName**: key + "s" (örn. "taggables") - **ForeignKeyColumn**: "tag_id" (ana tablonun foreign key'i) - **RelatedKeyColumn**: key + "_id" (örn. "taggable_id") - **MorphTypeColumn**: key + "_type" (örn. "taggable_type") - **LoadingStrategy**: EAGER_LOADING
Döndürür:
- Yapılandırılmış MorphToMany pointer'ı
func (*MorphToMany) AutoOptions ¶
func (m *MorphToMany) AutoOptions(displayField string) *MorphToMany
AutoOptions, ilişkili tablodan otomatik options oluşturmayı etkinleştirir.
Bu metod, MorphToMany ilişkisinde ilişkili kayıtların otomatik olarak yüklenmesini ve frontend'de multi-select combobox'ta gösterilmesini sağlar.
Parametreler ¶
- **displayField**: Option label'ı için kullanılacak sütun adı (örn. "name", "title")
Kullanım Örneği ¶
field := fields.NewMorphToMany("Taggable", "taggable").
Types(map[string]string{
"post": "posts",
"video": "videos",
}).
AutoOptions("name") // Ana tablodaki "name" sütunu label olarak kullanılır
Döndürür:
- MorphToMany pointer'ı (method chaining için)
func (*MorphToMany) Displays ¶
func (m *MorphToMany) Displays(displays map[string]string) *MorphToMany
Displays, her tip için görüntüleme alanını ayarlar.
Parametreler ¶
- **displays**: Tip değeri -> görüntüleme alanı eşlemesi (örn. {"post": "title", "video": "name"})
Kullanım Örneği ¶
field := fields.NewMorphToMany("Taggable", "taggable").
Displays(map[string]string{
"post": "title",
"video": "name",
})
Döndürür:
- MorphToMany pointer'ı (method chaining için)
func (*MorphToMany) ForeignKey ¶
func (m *MorphToMany) ForeignKey(key string) *MorphToMany
ForeignKey, ana tablonun foreign key sütun adını ayarlar.
Parametreler ¶
- **key**: Foreign key sütun adı (örn. "tag_id")
Döndürür:
- MorphToMany pointer'ı (method chaining için)
func (*MorphToMany) GetDisplayKey ¶
func (m *MorphToMany) GetDisplayKey() string
GetDisplayKey, görüntüleme key'ini döndürür.
func (*MorphToMany) GetLoadingStrategy ¶
func (m *MorphToMany) GetLoadingStrategy() LoadingStrategy
GetLoadingStrategy, yükleme stratejisini döndürür.
func (*MorphToMany) GetQueryCallback ¶
func (m *MorphToMany) GetQueryCallback() func(interface{}) interface{}
GetQueryCallback, sorgu callback'ini döndürür.
func (*MorphToMany) GetRelatedResource ¶
func (m *MorphToMany) GetRelatedResource() string
GetRelatedResource, ilgili resource slug'ını döndürür. MorphToMany için uygulanamaz çünkü birden fazla resource'a ait olabilir.
func (*MorphToMany) GetRelationshipName ¶
func (m *MorphToMany) GetRelationshipName() string
GetRelationshipName, ilişkinin adını döndürür.
func (*MorphToMany) GetRelationshipType ¶
func (m *MorphToMany) GetRelationshipType() string
GetRelationshipType, ilişki türünü döndürür.
func (*MorphToMany) GetSearchableColumns ¶
func (m *MorphToMany) GetSearchableColumns() []string
GetSearchableColumns, aranabilir sütunları döndürür.
func (*MorphToMany) GetTypes ¶
func (m *MorphToMany) GetTypes() map[string]string
GetTypes, tip eşlemelerini döndürür.
func (*MorphToMany) IsRequired ¶
func (m *MorphToMany) IsRequired() bool
IsRequired, alanın zorunlu olup olmadığını döndürür.
func (*MorphToMany) MorphType ¶
func (m *MorphToMany) MorphType(column string) *MorphToMany
MorphType, polimorfik tip sütun adını ayarlar.
Parametreler ¶
- **column**: Polimorfik tip sütun adı (örn. "taggable_type")
Döndürür:
- MorphToMany pointer'ı (method chaining için)
func (*MorphToMany) PivotTable ¶
func (m *MorphToMany) PivotTable(tableName string) *MorphToMany
PivotTable, pivot tablo adını özelleştirir.
Parametreler ¶
- **tableName**: Pivot tablo adı (örn. "taggables", "imageables")
Döndürür:
- MorphToMany pointer'ı (method chaining için)
func (*MorphToMany) Query ¶
func (m *MorphToMany) Query(fn func(interface{}) interface{}) *MorphToMany
Query, ilişki sorgusunu özelleştirmek için callback ayarlar.
func (*MorphToMany) RelatedKey ¶
func (m *MorphToMany) RelatedKey(key string) *MorphToMany
RelatedKey, polimorfik ID sütun adını ayarlar.
Parametreler ¶
- **key**: Polimorfik ID sütun adı (örn. "taggable_id")
Döndürür:
- MorphToMany pointer'ı (method chaining için)
func (*MorphToMany) ResolveRelationship ¶
func (m *MorphToMany) ResolveRelationship(item interface{}) (interface{}, error)
ResolveRelationship, polimorfik many-to-many ilişkiyi çözümler.
func (*MorphToMany) Searchable ¶
func (m *MorphToMany) Searchable() Element
Searchable, alanı aranabilir olarak işaretler.
func (*MorphToMany) Types ¶
func (m *MorphToMany) Types(types map[string]string) *MorphToMany
Types, polimorfik ilişki için tip eşlemelerini ayarlar.
Parametreler ¶
- **types**: Tip değeri -> resource slug eşlemesi (örn. {"post": "posts", "video": "videos"})
Kullanım Örneği ¶
field := fields.NewMorphToMany("Taggable", "taggable").
Types(map[string]string{
"post": "posts",
"video": "videos",
})
Döndürür:
- MorphToMany pointer'ı (method chaining için)
func (*MorphToMany) ValidateRelationship ¶
func (m *MorphToMany) ValidateRelationship(value interface{}) error
ValidateRelationship, ilişkiyi doğrular.
func (*MorphToMany) WithEagerLoad ¶
func (m *MorphToMany) WithEagerLoad() *MorphToMany
WithEagerLoad, yükleme stratejisini eager loading olarak ayarlar.
func (*MorphToMany) WithLazyLoad ¶
func (m *MorphToMany) WithLazyLoad() *MorphToMany
WithLazyLoad, yükleme stratejisini lazy loading olarak ayarlar.
type PanelField ¶
PanelField, alanları bölümlere/kartlara gruplamak için bir konteyner temsil eder.
Panel, ilgili alanları görsel olarak gruplamak ve organize etmek için kullanılır. Form sayfalarında alanları mantıksal bölümlere ayırmak için idealdir.
Kullanım Senaryoları ¶
- **Profil Bilgileri**: Ad, soyad, e-posta gibi kişisel bilgileri grupla - **Adres Bilgileri**: Şehir, ilçe, posta kodu gibi adres alanlarını grupla - **Güvenlik Ayarları**: Şifre, 2FA gibi güvenlik alanlarını grupla
Özellikler ¶
- **Başlık**: Panel başlığı - **Açıklama**: Panel açıklaması (opsiyonel) - **Sütun Sayısı**: Grid sütun sayısı (1-4) - **Daraltılabilir**: Panel daraltılabilir/genişletilebilir - **Varsayılan Daraltılmış**: Panel varsayılan olarak daraltılmış
Kullanım Örneği ¶
panel := fields.Panel("Kişisel Bilgiler",
fields.Text("Ad", "first_name"),
fields.Text("Soyad", "last_name"),
fields.Email("E-posta", "email"),
).WithDescription("Kullanıcının kişisel bilgileri").
WithColumns(2).
Collapsible()
func Panel ¶
func Panel(title string, fields ...core.Element) *PanelField
Panel, alanları gruplamak için yeni bir panel/bölüm oluşturur.
Bu fonksiyon, ilgili alanları görsel olarak gruplamak için bir konteyner oluşturur. Form sayfalarında alanları mantıksal bölümlere ayırmak için kullanılır.
Parametreler ¶
- **title**: Panel başlığı (örn. "Kişisel Bilgiler", "Adres Bilgileri") - **fields**: Panel içinde görüntülenecek alanlar
Kullanım Örneği ¶
panel := fields.Panel("Kişisel Bilgiler",
fields.Text("Ad", "first_name"),
fields.Text("Soyad", "last_name"),
fields.Email("E-posta", "email"),
)
Döndürür:
- Yapılandırılmış PanelField pointer'ı
func (*PanelField) Collapsible ¶
func (p *PanelField) Collapsible() *PanelField
Collapsible, panel'i daraltılabilir yapar.
Bu metod, panel başlığına tıklandığında panel içeriğinin daraltılıp genişletilebilmesini sağlar. Uzun formlarda alan tasarrufu sağlamak için kullanılır.
Kullanım Örneği ¶
panel.Collapsible() // Panel başlığına tıklandığında içerik daraltılır/genişletilir
Döndürür:
- PanelField pointer'ı (method chaining için)
func (*PanelField) DefaultCollapsed ¶
func (p *PanelField) DefaultCollapsed() *PanelField
DefaultCollapsed, panel'in varsayılan olarak daraltılmış olmasını sağlar.
Bu metod, panel'in sayfa yüklendiğinde daraltılmış olarak görüntülenmesini sağlar. Kullanıcı panel başlığına tıklayarak içeriği genişletebilir.
Kullanım Örneği ¶
panel.DefaultCollapsed() // Panel sayfa yüklendiğinde daraltılmış olarak görüntülenir
Önemli Notlar ¶
- Bu metod otomatik olarak Collapsible() özelliğini de aktif eder
Döndürür:
- PanelField pointer'ı (method chaining için)
func (*PanelField) GetFields ¶
func (p *PanelField) GetFields() []core.Element
GetFields, bu panel içindeki alanları döndürür.
Döndürür:
- Panel içindeki alanların listesi
func (*PanelField) WithColumns ¶
func (p *PanelField) WithColumns(columns int) *PanelField
WithColumns, panel için grid sütun sayısını ayarlar (1-4).
Bu metod, panel içindeki alanların kaç sütunda görüntüleneceğini belirler. Sütun sayısı 1 ile 4 arasında olmalıdır.
Parametreler ¶
- **columns**: Sütun sayısı (1-4 arası)
Kullanım Örneği ¶
panel.WithColumns(2) // Alanlar 2 sütunda görüntülenir panel.WithColumns(3) // Alanlar 3 sütunda görüntülenir
Önemli Notlar ¶
- Sütun sayısı 1'den küçükse 1'e ayarlanır - Sütun sayısı 4'ten büyükse 4'e ayarlanır
Döndürür:
- PanelField pointer'ı (method chaining için)
func (*PanelField) WithDescription ¶
func (p *PanelField) WithDescription(description string) *PanelField
WithDescription, panel'e açıklama ekler.
Bu metod, panel başlığının altında görüntülenecek açıklayıcı bir metin ekler. Kullanıcılara panel içeriği hakkında bilgi vermek için kullanılır.
Parametreler ¶
- **description**: Panel açıklaması
Kullanım Örneği ¶
panel.WithDescription("Kullanıcının kişisel bilgilerini girin")
Döndürür:
- PanelField pointer'ı (method chaining için)
type Post ¶
type Post struct {
// ID, gönderinin benzersiz kimliğidir (primary key).
ID int `json:"id"`
// UserID, gönderinin sahibi olan kullanıcının ID'sidir (foreign key).
UserID int `json:"user_id"`
// Title, gönderinin başlığıdır.
Title string `json:"title"`
// Content, gönderinin içeriğidir.
Content string `json:"content"`
// Author, gönderinin sahibi olan kullanıcıdır (BelongsTo ilişkisi).
// Bu alan opsiyoneldir ve eager loading ile doldurulur.
Author *User `json:"author,omitempty"`
}
Post, bir blog gönderisini temsil eden model yapısıdır.
Bu model, kullanıcılar tarafından oluşturulan içerikleri tutar ve BelongsTo, HasMany ve BelongsToMany ilişkilerinin test edilmesinde kullanılır.
İlişkiler ¶
- **BelongsTo**: User (her gönderi bir kullanıcıya aittir) - **HasMany**: Comments (bir gönderinin birden fazla yorumu olabilir) - **BelongsToMany**: Tags (bir gönderi birden fazla etikete sahip olabilir)
JSON Serileştirme ¶
Author alanı opsiyoneldir ve `omitempty` ile işaretlenmiştir. İlişki yüklenmemişse JSON'da görünmez.
Örnek Kullanım ¶
```go var post Post err := db.QueryRow(`
SELECT p.id, p.user_id, p.title, p.content,
u.id, u.name, u.email
FROM posts p
LEFT JOIN users u ON p.user_id = u.id
WHERE p.id = ?
`, 1).Scan(&post.ID, &post.UserID, &post.Title, &post.Content,
&post.Author.ID, &post.Author.Name, &post.Author.Email)
```
type PostTag ¶
type PostTag struct {
// PostID, gönderinin ID'sidir (composite primary key'in bir parçası).
PostID int `json:"post_id"`
// TagID, etiketin ID'sidir (composite primary key'in bir parçası).
TagID int `json:"tag_id"`
}
PostTag, gönderi-etiket ilişkisini temsil eden pivot model yapısıdır.
Bu model, Post ve Tag arasındaki çoka-çok (many-to-many) ilişkiyi tutar. BelongsToMany ilişkisinin test edilmesinde kullanılır.
İlişki Türü ¶
Bu bir **pivot tablo** modelidir ve iki model arasındaki çoka-çok ilişkiyi sağlar: - Bir gönderi birden fazla etikete sahip olabilir - Bir etiket birden fazla gönderide kullanılabilir
Veritabanı Yapısı ¶
- Composite primary key (post_id, tag_id) - Foreign key: post_id -> posts.id - Foreign key: tag_id -> tags.id
Önemli Notlar ¶
- Bu tablo ek veri tutmaz, sadece ilişkiyi tanımlar - Composite primary key sayesinde aynı ilişki iki kez eklenemez - Pivot tablolar genellikle ek metadata tutabilir (created_at, vb.)
Örnek Kullanım ¶
```go // Bir gönderiye etiket ekle _, err := db.Exec("INSERT INTO post_tag (post_id, tag_id) VALUES (?, ?)", 1, 2)
// Bir gönderinin tüm etiketlerini getir rows, err := db.Query(`
SELECT t.id, t.name FROM tags t JOIN post_tag pt ON t.id = pt.tag_id WHERE pt.post_id = ?
`, 1) ```
type Profile ¶
type Profile struct {
// ID, profilin benzersiz kimliğidir (primary key).
ID int `json:"id"`
// UserID, profilin ait olduğu kullanıcının ID'sidir (foreign key, unique).
UserID int `json:"user_id"`
// Bio, kullanıcının biyografisidir.
Bio string `json:"bio"`
// AvatarURL, kullanıcının profil resminin URL'sidir.
AvatarURL string `json:"avatar_url"`
// User, profilin ait olduğu kullanıcıdır (BelongsTo ilişkisi).
// Bu alan opsiyoneldir ve eager loading ile doldurulur.
User *User `json:"user,omitempty"`
}
Profile, bir kullanıcı profilini temsil eden model yapısıdır.
Bu model, kullanıcıların ek bilgilerini tutar ve HasOne ilişkisinin test edilmesinde kullanılır. Her kullanıcının yalnızca bir profili olabilir.
İlişkiler ¶
- **BelongsTo**: User (her profil bir kullanıcıya aittir) - **HasOne** (ters yönde): User -> Profile
JSON Serileştirme ¶
User alanı opsiyoneldir ve `omitempty` ile işaretlenmiştir. İlişki yüklenmemişse JSON'da görünmez.
Önemli Notlar ¶
- UserID alanı UNIQUE constraint'e sahiptir - Bir kullanıcının yalnızca bir profili olabilir - Profil olmadan kullanıcı var olabilir (opsiyonel ilişki)
Örnek Kullanım ¶
```go var profile Profile err := db.QueryRow(`
SELECT p.id, p.user_id, p.bio, p.avatar_url,
u.id, u.name, u.email
FROM profiles p
LEFT JOIN users u ON p.user_id = u.id
WHERE p.user_id = ?
`, 1).Scan(&profile.ID, &profile.UserID, &profile.Bio, &profile.AvatarURL,
&profile.User.ID, &profile.User.Name, &profile.User.Email)
```
type RelationshipConstraints ¶
type RelationshipConstraints interface {
// ApplyLimit, sorgu sonuç sayısını sınırlar.
//
// # Parametreler
//
// - `ctx`: Context nesnesi
// - `limit`: Maksimum sonuç sayısı (negatif değerler 0'a dönüştürülür)
//
// # Döndürür
//
// - `[]interface{}`: Kısıtlanmış sonuç listesi
// - `error`: Hata durumunda hata nesnesi
//
// # Örnek
//
// “`go
// results, err := constraints.ApplyLimit(ctx, 10)
// if err != nil {
// log.Fatal(err)
// }
// “`
ApplyLimit(ctx context.Context, limit int) ([]interface{}, error)
// ApplyOffset, sorgu başlangıç noktasını kaydırır.
//
// # Parametreler
//
// - `ctx`: Context nesnesi
// - `offset`: Kaç kayıt atlanacağı (negatif değerler 0'a dönüştürülür)
//
// # Döndürür
//
// - `[]interface{}`: Kaydırılmış sonuç listesi
// - `error`: Hata durumunda hata nesnesi
//
// # Örnek
//
// “`go
// // İlk 5 kaydı atla
// results, err := constraints.ApplyOffset(ctx, 5)
// if err != nil {
// log.Fatal(err)
// }
// “`
ApplyOffset(ctx context.Context, offset int) ([]interface{}, error)
// ApplyWhere, sorguya WHERE koşulu ekler.
//
// # Parametreler
//
// - `ctx`: Context nesnesi
// - `column`: Koşul uygulanacak sütun adı
// - `operator`: Karşılaştırma operatörü (=, !=, >, <, >=, <=, LIKE, vb.)
// - `value`: Karşılaştırılacak değer
//
// # Döndürür
//
// - `[]interface{}`: Filtrelenmiş sonuç listesi
// - `error`: Hata durumunda hata nesnesi
//
// # Örnek
//
// “`go
// // Aktif kayıtları getir
// results, err := constraints.ApplyWhere(ctx, "status", "=", "active")
//
// // Fiyatı 100'den büyük olanları getir
// results, err = constraints.ApplyWhere(ctx, "price", ">", 100)
// “`
//
// # Not
//
// Boş column değeri durumunda işlem yapılmaz ve boş liste döner.
ApplyWhere(ctx context.Context, column string, operator string, value interface{}) ([]interface{}, error)
// ApplyWhereIn, sorguya WHERE IN koşulu ekler.
//
// # Parametreler
//
// - `ctx`: Context nesnesi
// - `column`: Koşul uygulanacak sütun adı
// - `values`: Kontrol edilecek değerler listesi
//
// # Döndürür
//
// - `[]interface{}`: Filtrelenmiş sonuç listesi
// - `error`: Hata durumunda hata nesnesi
//
// # Örnek
//
// “`go
// // Belirli ID'lere sahip kayıtları getir
// results, err := constraints.ApplyWhereIn(ctx, "id", []interface{}{1, 2, 3, 5, 8})
//
// // Belirli kategorilerdeki kayıtları getir
// results, err = constraints.ApplyWhereIn(ctx, "category", []interface{}{"tech", "science", "art"})
// “`
//
// # Not
//
// Boş column veya values durumunda işlem yapılmaz ve boş liste döner.
ApplyWhereIn(ctx context.Context, column string, values []interface{}) ([]interface{}, error)
}
RelationshipConstraints, ilişkisel alanlar için sorgu kısıtlamaları uygulayan interface'dir.
Bu interface, relationship field'ları üzerinde LIMIT, OFFSET, WHERE ve WHERE IN gibi SQL kısıtlamalarını uygulamak için metodlar sağlar. Her metod context alır ve sonuçları döndürür.
Metodlar ¶
- `ApplyLimit`: Sorgu sonuç sayısını sınırlar - `ApplyOffset`: Sorgu başlangıç noktasını kaydırır - `ApplyWhere`: WHERE koşulu ekler - `ApplyWhereIn`: WHERE IN koşulu ekler
Örnek Kullanım ¶
```go constraints := NewRelationshipConstraints(relationshipField)
// Limit uygula results, err := constraints.ApplyLimit(ctx, 10)
// Offset uygula results, err = constraints.ApplyOffset(ctx, 5)
// WHERE koşulu ekle results, err = constraints.ApplyWhere(ctx, "status", "=", "active")
// WHERE IN koşulu ekle results, err = constraints.ApplyWhereIn(ctx, "id", []interface{}{1, 2, 3}) ```
Referans ¶
Detaylı bilgi için: docs/Relationships.md(../../docs/Relationships.md)
type RelationshipConstraintsImpl ¶
type RelationshipConstraintsImpl struct {
// contains filtered or unexported fields
}
RelationshipConstraintsImpl, RelationshipConstraints interface'inin implementasyonudur.
Bu struct, relationship field'ları üzerinde sorgu kısıtlamalarını yönetir. Limit, offset ve WHERE koşullarını saklar ve uygular.
Alanlar ¶
- `field`: İlişkili field nesnesi - `limit`: Maksimum sonuç sayısı (0 = sınırsız) - `offset`: Atlanacak kayıt sayısı - `constraints`: WHERE koşulları map'i
Örnek Kullanım ¶
```go // Yeni constraints handler oluştur constraints := NewRelationshipConstraints(relationshipField)
// Kısıtlamaları uygula constraints.ApplyLimit(ctx, 10) constraints.ApplyOffset(ctx, 5) constraints.ApplyWhere(ctx, "status", "=", "active")
// Değerleri oku limit := constraints.GetLimit() // 10 offset := constraints.GetOffset() // 5 where := constraints.GetConstraints() // map[status:...] ```
Referans ¶
Detaylı bilgi için: docs/Relationships.md(../../docs/Relationships.md)
func NewRelationshipConstraints ¶
func NewRelationshipConstraints(field RelationshipField) *RelationshipConstraintsImpl
NewRelationshipConstraints, yeni bir relationship constraints handler oluşturur.
Bu constructor, verilen relationship field için kısıtlama yöneticisi oluşturur. Tüm kısıtlamalar varsayılan değerlerle (limit=0, offset=0, boş constraints) başlatılır.
Parametreler ¶
- `field`: Kısıtlamaların uygulanacağı RelationshipField nesnesi
Döndürür ¶
- Yapılandırılmış RelationshipConstraintsImpl pointer'ı
Örnek ¶
```go // Relationship field oluştur relationshipField := fields.NewBelongsTo("user", "User")
// Constraints handler oluştur constraints := NewRelationshipConstraints(relationshipField)
// Kısıtlamaları uygula results, err := constraints.ApplyLimit(ctx, 10)
if err != nil {
log.Fatal(err)
}
```
Not ¶
- Limit ve offset başlangıçta 0 olarak ayarlanır - Constraints map'i boş olarak başlatılır - Field parametresi nil olmamalıdır
Referans ¶
Detaylı bilgi için: docs/Relationships.md(../../docs/Relationships.md)
func (*RelationshipConstraintsImpl) ApplyLimit ¶
func (rc *RelationshipConstraintsImpl) ApplyLimit(ctx context.Context, limit int) ([]interface{}, error)
ApplyLimit, sorgu sonuç sayısını sınırlar.
Bu metod, relationship sorgusu için maksimum sonuç sayısını belirler. Negatif değerler otomatik olarak 0'a dönüştürülür.
Parametreler ¶
- `ctx`: Context nesnesi (timeout, cancellation için) - `limit`: Maksimum sonuç sayısı (0 = sınırsız, negatif değerler 0'a çevrilir)
Döndürür ¶
- `[]interface{}`: Kısıtlanmış sonuç listesi (şu anki implementasyonda boş) - `error`: Hata durumunda hata nesnesi
Örnek ¶
```go constraints := NewRelationshipConstraints(relationshipField)
// İlk 10 kaydı getir results, err := constraints.ApplyLimit(ctx, 10)
if err != nil {
log.Fatal(err)
}
// Limit değerini kontrol et fmt.Println(constraints.GetLimit()) // 10 ```
Not ¶
- Negatif limit değerleri 0'a dönüştürülür - Limit değeri struct içinde saklanır - Gerçek implementasyonda bu değer sorguya uygulanır
func (*RelationshipConstraintsImpl) ApplyOffset ¶
func (rc *RelationshipConstraintsImpl) ApplyOffset(ctx context.Context, offset int) ([]interface{}, error)
ApplyOffset, sorgu başlangıç noktasını kaydırır.
Bu metod, relationship sorgusu için kaç kaydın atlanacağını belirler. Pagination (sayfalama) işlemleri için kullanılır. Negatif değerler otomatik olarak 0'a dönüştürülür.
Parametreler ¶
- `ctx`: Context nesnesi (timeout, cancellation için) - `offset`: Atlanacak kayıt sayısı (negatif değerler 0'a çevrilir)
Döndürür ¶
- `[]interface{}`: Kaydırılmış sonuç listesi (şu anki implementasyonda boş) - `error`: Hata durumunda hata nesnesi
Örnek ¶
```go constraints := NewRelationshipConstraints(relationshipField)
// Sayfa 2 için (her sayfada 10 kayıt) constraints.ApplyLimit(ctx, 10) results, err := constraints.ApplyOffset(ctx, 10)
if err != nil {
log.Fatal(err)
}
// Offset değerini kontrol et fmt.Println(constraints.GetOffset()) // 10 ```
Not ¶
- Negatif offset değerleri 0'a dönüştürülür - Offset değeri struct içinde saklanır - Genellikle limit ile birlikte kullanılır (pagination) - Gerçek implementasyonda bu değer sorguya uygulanır
func (*RelationshipConstraintsImpl) ApplyWhere ¶
func (rc *RelationshipConstraintsImpl) ApplyWhere(ctx context.Context, column string, operator string, value interface{}) ([]interface{}, error)
ApplyWhere, sorguya WHERE koşulu ekler.
Bu metod, relationship sorgusu için WHERE koşulu ekler. Belirtilen sütun, operatör ve değer kullanılarak filtreleme yapılır. Koşul constraints map'inde saklanır ve gerçek implementasyonda sorguya uygulanır.
Parametreler ¶
- `ctx`: Context nesnesi (timeout, cancellation için) - `column`: Koşul uygulanacak sütun adı (boş olamaz) - `operator`: Karşılaştırma operatörü (=, !=, >, <, >=, <=, LIKE, vb.) - `value`: Karşılaştırılacak değer (herhangi bir tip olabilir)
Döndürür ¶
- `[]interface{}`: Filtrelenmiş sonuç listesi (şu anki implementasyonda boş) - `error`: Hata durumunda hata nesnesi
Örnek ¶
```go constraints := NewRelationshipConstraints(relationshipField)
// Aktif kayıtları getir results, err := constraints.ApplyWhere(ctx, "status", "=", "active")
if err != nil {
log.Fatal(err)
}
// Fiyatı 100'den büyük olanları getir results, err = constraints.ApplyWhere(ctx, "price", ">", 100)
// LIKE operatörü ile arama results, err = constraints.ApplyWhere(ctx, "name", "LIKE", "%test%")
// Koşulları kontrol et constraints := constraints.GetConstraints() fmt.Println(constraints["status"]) // map[operator:= value:active] ```
Not ¶
- Boş column değeri durumunda işlem yapılmaz ve boş liste döner - Aynı sütun için birden fazla koşul eklenirse son eklenen geçerli olur - Koşul map formatında saklanır: map[operator:... value:...] - Gerçek implementasyonda bu koşul sorguya uygulanır
Desteklenen Operatörler ¶
- `=`: Eşittir - `!=`: Eşit değildir - `>`: Büyüktür - `<`: Küçüktür - `>=`: Büyük eşittir - `<=`: Küçük eşittir - `LIKE`: Benzer (pattern matching) - `NOT LIKE`: Benzer değil
func (*RelationshipConstraintsImpl) ApplyWhereIn ¶
func (rc *RelationshipConstraintsImpl) ApplyWhereIn(ctx context.Context, column string, values []interface{}) ([]interface{}, error)
ApplyWhereIn, sorguya WHERE IN koşulu ekler.
Bu metod, relationship sorgusu için WHERE IN koşulu ekler. Belirtilen sütunun değerinin verilen değerler listesinde olup olmadığını kontrol eder. Koşul constraints map'inde saklanır ve gerçek implementasyonda sorguya uygulanır.
Parametreler ¶
- `ctx`: Context nesnesi (timeout, cancellation için) - `column`: Koşul uygulanacak sütun adı (boş olamaz) - `values`: Kontrol edilecek değerler listesi (boş olamaz)
Döndürür ¶
- `[]interface{}`: Filtrelenmiş sonuç listesi (şu anki implementasyonda boş) - `error`: Hata durumunda hata nesnesi
Örnek ¶
```go constraints := NewRelationshipConstraints(relationshipField)
// Belirli ID'lere sahip kayıtları getir results, err := constraints.ApplyWhereIn(ctx, "id", []interface{}{1, 2, 3, 5, 8})
if err != nil {
log.Fatal(err)
}
// Belirli kategorilerdeki kayıtları getir results, err = constraints.ApplyWhereIn(ctx, "category", []interface{}{"tech", "science", "art"})
// Belirli durumlardaki kayıtları getir results, err = constraints.ApplyWhereIn(ctx, "status", []interface{}{"active", "pending", "approved"})
// Koşulları kontrol et constraints := constraints.GetConstraints() fmt.Println(constraints["id"]) // map[in:[1 2 3 5 8]] ```
Not ¶
- Boş column veya values durumunda işlem yapılmaz ve boş liste döner - Aynı sütun için birden fazla koşul eklenirse son eklenen geçerli olur - Koşul map formatında saklanır: map[in:[...]] - Gerçek implementasyonda bu koşul sorguya uygulanır - Values listesi herhangi bir tip içerebilir (int, string, vb.)
Performans Notu ¶
WHERE IN sorguları büyük değer listeleri ile yavaş olabilir. Çok sayıda değer için alternatif yöntemler düşünülmelidir.
func (*RelationshipConstraintsImpl) GetConstraints ¶
func (rc *RelationshipConstraintsImpl) GetConstraints() map[string]interface{}
GetConstraints, tüm WHERE koşullarını döndürür.
Bu metod, ApplyWhere ve ApplyWhereIn ile eklenen tüm koşulları map formatında döndürür. Her sütun için koşul bilgisi içerir.
Döndürür ¶
- WHERE koşulları map'i (sütun adı -> koşul detayları)
Map Formatı ¶
WHERE koşulu için: ```go
map[string]interface{}{
"column_name": map[string]interface{}{
"operator": "=",
"value": "some_value",
},
}
```
WHERE IN koşulu için: ```go
map[string]interface{}{
"column_name": map[string]interface{}{
"in": []interface{}{1, 2, 3},
},
}
```
Örnek ¶
```go constraints := NewRelationshipConstraints(relationshipField) constraints.ApplyWhere(ctx, "status", "=", "active") constraints.ApplyWhereIn(ctx, "id", []interface{}{1, 2, 3})
allConstraints := constraints.GetConstraints() fmt.Println(allConstraints) // Output: // map[ // status:map[operator:= value:active] // id:map[in:[1 2 3]] // ]
// Belirli bir koşulu kontrol et
if statusConstraint, ok := allConstraints["status"]; ok {
constraint := statusConstraint.(map[string]interface{})
fmt.Println(constraint["operator"]) // =
fmt.Println(constraint["value"]) // active
}
```
Not ¶
- Döndürülen map referans olarak döner, değişiklikler orijinal map'i etkiler - Boş map döndürülmesi hiç koşul eklenmediği anlamına gelir
func (*RelationshipConstraintsImpl) GetLimit ¶
func (rc *RelationshipConstraintsImpl) GetLimit() int
GetLimit, mevcut limit değerini döndürür.
Bu metod, ApplyLimit ile ayarlanan limit değerini okur.
Döndürür ¶
- Mevcut limit değeri (0 = sınırsız)
Örnek ¶
```go constraints := NewRelationshipConstraints(relationshipField) constraints.ApplyLimit(ctx, 10)
limit := constraints.GetLimit() fmt.Println(limit) // 10 ```
func (*RelationshipConstraintsImpl) GetOffset ¶
func (rc *RelationshipConstraintsImpl) GetOffset() int
GetOffset, mevcut offset değerini döndürür.
Bu metod, ApplyOffset ile ayarlanan offset değerini okur.
Döndürür ¶
- Mevcut offset değeri (0 = baştan başla)
Örnek ¶
```go constraints := NewRelationshipConstraints(relationshipField) constraints.ApplyOffset(ctx, 20)
offset := constraints.GetOffset() fmt.Println(offset) // 20 ```
type RelationshipCounting ¶
type RelationshipCounting interface {
// Count, ilişkili kaynakların sayısını döndürür.
//
// # Parametreler
//
// - `ctx`: İşlem context'i (timeout, iptal kontrolü için)
//
// # Dönüş Değerleri
//
// - `int64`: İlişkili kaynak sayısı
// - `error`: Hata durumunda hata mesajı
//
// # İlişki Türlerine Göre Davranış
//
// | İlişki Türü | Dönüş Değeri |
// |----------------|---------------------------|
// | belongsTo | 0 veya 1 |
// | hasOne | 0 veya 1 |
// | hasMany | İlişkili kaynak sayısı |
// | belongsToMany | Pivot tablo kayıt sayısı |
// | morphTo | 0 veya 1 |
Count(ctx context.Context) (int64, error)
}
RelationshipCounting, ilişkiler için sayma işlevselliğini yöneten interface'dir.
Bu interface, farklı ilişki türlerindeki ilişkili kaynakların sayısını hesaplamak için kullanılır. Her ilişki türü kendi sayma mantığına sahiptir.
Kullanım Örneği ¶
```go counter := NewRelationshipCounting(relationshipField) count, err := counter.Count(ctx)
if err != nil {
log.Fatal(err)
}
fmt.Printf("İlişkili kaynak sayısı: %d\n", count) ```
Önemli Notlar ¶
- Context parametresi timeout ve iptal işlemleri için kullanılır - Hata durumunda 0 ve ilgili hata döner - Bilinmeyen ilişki türleri için 0 döner (hata vermez)
type RelationshipCountingImpl ¶
type RelationshipCountingImpl struct {
// contains filtered or unexported fields
}
RelationshipCountingImpl, RelationshipCounting interface'inin varsayılan implementasyonudur.
Bu struct, ilişki alanı (RelationshipField) üzerinden ilişki türünü tespit eder ve uygun sayma metodunu çağırır.
Kullanım Örneği ¶
```go // Constructor ile oluşturma (önerilen) counter := NewRelationshipCounting(relationshipField)
// Manuel oluşturma
counter := &RelationshipCountingImpl{
field: relationshipField,
}
// Sayma işlemi count, err := counter.Count(context.Background()) ```
Önemli Notlar ¶
- Constructor fonksiyonu (`NewRelationshipCounting`) kullanımı önerilir - `field` parametresi nil olmamalıdır - Thread-safe değildir, concurrent kullanım için senkronizasyon gerekir
func NewRelationshipCounting ¶
func NewRelationshipCounting(field RelationshipField) *RelationshipCountingImpl
NewRelationshipCounting, yeni bir RelationshipCountingImpl instance'ı oluşturur.
Bu constructor fonksiyonu, ilişki sayma işlevselliği için gerekli yapılandırmayı yapar ve kullanıma hazır bir instance döner.
Parametreler ¶
- `field`: İlişki alanı (RelationshipField interface'ini implement etmeli)
Dönüş Değerleri ¶
- `*RelationshipCountingImpl`: Yapılandırılmış RelationshipCountingImpl pointer'ı
Kullanım Örneği ¶
```go // BelongsTo ilişkisi için belongsToField := NewBelongsTo("author", &User{}) counter := NewRelationshipCounting(belongsToField) count, _ := counter.Count(ctx)
// HasMany ilişkisi için hasManyField := NewHasMany("posts", &Post{}) counter := NewRelationshipCounting(hasManyField) count, _ := counter.Count(ctx)
// BelongsToMany ilişkisi için manyToManyField := NewBelongsToMany("tags", &Tag{}, "post_tags") counter := NewRelationshipCounting(manyToManyField) count, _ := counter.Count(ctx) ```
Önemli Notlar ¶
- `field` parametresi nil olmamalıdır - Dönen pointer nil kontrolü gerektirmez (her zaman geçerli bir instance döner) - Method chaining için uygun değildir (immutable pattern kullanılmamıştır)
Referanslar ¶
İlişki türleri hakkında detaylı bilgi: `docs/Relationships.md`
func (*RelationshipCountingImpl) Count ¶
func (rc *RelationshipCountingImpl) Count(ctx context.Context) (int64, error)
Count, ilişkili kaynakların sayısını döndürür.
Bu method, ilişki türünü tespit eder ve uygun sayma metodunu çağırır. Her ilişki türü için farklı sayma mantığı uygulanır.
Parametreler ¶
- `ctx`: İşlem context'i (timeout, iptal kontrolü için)
Dönüş Değerleri ¶
- `int64`: İlişkili kaynak sayısı - `error`: Hata durumunda hata mesajı
İlişki Türlerine Göre Davranış ¶
| İlişki Türü | Method | Dönüş Değeri | |----------------|---------------------|---------------------------| | belongsTo | countBelongsTo() | 0 veya 1 | | hasOne | countHasOne() | 0 veya 1 | | hasMany | countHasMany() | İlişkili kaynak sayısı | | belongsToMany | countBelongsToMany()| Pivot tablo kayıt sayısı | | morphTo | countMorphTo() | 0 veya 1 | | Bilinmeyen | - | 0 (hata vermez) |
Kullanım Örneği ¶
```go counter := NewRelationshipCounting(relationshipField)
// Context ile sayma ctx := context.Background() count, err := counter.Count(ctx)
if err != nil {
log.Printf("Sayma hatası: %v", err)
return
}
fmt.Printf("İlişkili kaynak sayısı: %d\n", count)
// Timeout ile sayma ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() count, err = counter.Count(ctx) ```
Önemli Notlar ¶
- Bilinmeyen ilişki türleri için 0 döner ve hata vermez - Context timeout veya iptal durumunda ilgili hata döner - Thread-safe değildir, concurrent kullanım için senkronizasyon gerekir
Referanslar ¶
İlişki türleri hakkında detaylı bilgi: `docs/Relationships.md`
type RelationshipDisplay ¶
type RelationshipDisplay interface {
// GetDisplayValue, bir ilişki için görüntüleme değerini döndürür
GetDisplayValue(item interface{}) (string, error)
// GetDisplayValues, birden fazla öğe için görüntüleme değerlerini döndürür
GetDisplayValues(items []interface{}) ([]string, error)
// FormatDisplayValue, bir görüntüleme değerini formatlar
FormatDisplayValue(value interface{}) string
}
RelationshipDisplay, ilişkiler için görüntüleme özelleştirmesini yönetir.
Bu interface, ilişkili kayıtların nasıl görüntüleneceğini kontrol eder. Her ilişki türü için farklı görüntüleme stratejileri sağlar.
Kullanım Örneği ¶
display := fields.NewRelationshipDisplay(field) value, err := display.GetDisplayValue(item)
Daha fazla bilgi için docs/Relationships.md dosyasına bakın.
type RelationshipDisplayImpl ¶
type RelationshipDisplayImpl struct {
// contains filtered or unexported fields
}
RelationshipDisplayImpl, RelationshipDisplay interface'ini implement eder.
Bu yapı, ilişki görüntüleme işlemlerini gerçekleştirir. Her ilişki türü için özel görüntüleme mantığı sağlar.
func NewRelationshipDisplay ¶
func NewRelationshipDisplay(field RelationshipField) *RelationshipDisplayImpl
NewRelationshipDisplay, yeni bir relationship display handler oluşturur.
Bu fonksiyon, verilen field için görüntüleme handler'ı döndürür.
Parametreler ¶
- **field**: İlişki field'ı
Kullanım Örneği ¶
display := fields.NewRelationshipDisplay(field)
Döndürür:
- Yapılandırılmış RelationshipDisplayImpl pointer'ı
func (*RelationshipDisplayImpl) FormatDisplayValue ¶
func (rd *RelationshipDisplayImpl) FormatDisplayValue(value interface{}) string
FormatDisplayValue formats a display value
func (*RelationshipDisplayImpl) GetDisplayValue ¶
func (rd *RelationshipDisplayImpl) GetDisplayValue(item interface{}) (string, error)
GetDisplayValue returns the display value for a relationship
func (*RelationshipDisplayImpl) GetDisplayValues ¶
func (rd *RelationshipDisplayImpl) GetDisplayValues(items []interface{}) ([]string, error)
GetDisplayValues returns display values for multiple items
type RelationshipError ¶
type RelationshipError struct {
FieldName string
RelationshipType string
Message string
Context map[string]interface{}
}
RelationshipError, ilişki işlemleri sırasında oluşan bir hatayı temsil eder.
Bu hata tipi, ilişki işlemlerinde oluşan hataları daha iyi anlamak ve debug etmek için ek bağlam bilgisi sağlar.
Özellikler ¶
- **FieldName**: Hatanın oluştuğu alan adı - **RelationshipType**: İlişki türü (belongsTo, hasMany, vb.) - **Message**: Hata mesajı - **Context**: Ek bağlam bilgisi (map formatında)
Kullanım Örneği ¶
err := &RelationshipError{
FieldName: "author",
RelationshipType: "belongsTo",
Message: "related resource not found",
Context: map[string]interface{}{
"author_id": 123,
"resource": "authors",
},
}
func (*RelationshipError) Error ¶
func (e *RelationshipError) Error() string
Error, error interface'ini implement eder. Formatlanmış hata mesajı döndürür.
Döndürür:
- Formatlanmış hata mesajı (alan adı, ilişki türü ve mesaj içerir)
type RelationshipExistence ¶
type RelationshipExistence interface {
// Exists, ilişkili kaynakların var olup olmadığını kontrol eder.
//
// # Parametreler
//
// - `ctx`: Context nesnesi (timeout, cancellation için)
//
// # Dönüş Değerleri
//
// - `bool`: İlişkili kaynak varsa `true`, yoksa `false`
// - `error`: Kontrol sırasında oluşan hata, başarılıysa `nil`
//
// # Davranış
//
// İlişki tipine göre uygun EXISTS sorgusu çalıştırılır:
// - `belongsTo`: Foreign key üzerinden parent kaynak kontrolü
// - `hasMany`: Child kayıtların varlık kontrolü
// - `hasOne`: Child kaydın varlık kontrolü
// - `belongsToMany`: Pivot tablo üzerinden ilişki kontrolü
// - `morphTo`: Polimorfik ilişki kontrolü
Exists(ctx context.Context) (bool, error)
// DoesntExist, hiç ilişkili kaynak bulunmadığını kontrol eder.
//
// # Parametreler
//
// - `ctx`: Context nesnesi (timeout, cancellation için)
//
// # Dönüş Değerleri
//
// - `bool`: Hiç ilişkili kaynak yoksa `true`, varsa `false`
// - `error`: Kontrol sırasında oluşan hata, başarılıysa `nil`
//
// # Not
//
// Bu method, `Exists` metodunun tersini döndürür.
DoesntExist(ctx context.Context) (bool, error)
}
RelationshipExistence, ilişkili kaynakların varlık kontrolü için interface tanımlar.
Bu interface, relationship field'ların ilişkili kaynaklarının var olup olmadığını veya hiç ilişkili kaynak bulunmadığını kontrol etmek için kullanılır.
Metodlar ¶
- `Exists`: İlişkili kaynakların var olup olmadığını kontrol eder - `DoesntExist`: Hiç ilişkili kaynak bulunmadığını kontrol eder
Kullanım Örneği ¶
```go existence := NewRelationshipExistence(relationshipField)
// İlişkili kaynak var mı? exists, err := existence.Exists(ctx)
if err != nil {
return err
}
if exists {
fmt.Println("İlişkili kaynak bulundu")
}
// Hiç ilişkili kaynak yok mu? doesntExist, err := existence.DoesntExist(ctx)
if err != nil {
return err
}
if doesntExist {
fmt.Println("Hiç ilişkili kaynak yok")
}
```
Referans ¶
Detaylı bilgi için bkz: `docs/Relationships.md`
type RelationshipExistenceImpl ¶
type RelationshipExistenceImpl struct {
// contains filtered or unexported fields
}
RelationshipExistenceImpl, RelationshipExistence interface'ini implement eder.
Bu struct, relationship field'ların ilişkili kaynaklarının varlık kontrolü işlemlerini gerçekleştirir. İlişki tipine göre uygun EXISTS sorgusu stratejisini otomatik olarak seçer ve uygular.
Alanlar ¶
- `field`: Varlık kontrolü yapılacak relationship field
Kullanım Örneği ¶
```go // Relationship field oluştur belongsToField := fields.NewBelongsTo("author", "Author")
// Varlık kontrolcüsü oluştur existence := fields.NewRelationshipExistence(belongsToField)
// Varlık kontrolü yap exists, err := existence.Exists(context.Background())
if err != nil {
log.Fatal(err)
}
if exists {
fmt.Println("İlişkili kaynak mevcut")
}
```
Desteklenen İlişki Tipleri ¶
- `belongsTo`: Parent kaynak varlık kontrolü - `hasMany`: Child kayıtlar varlık kontrolü - `hasOne`: Child kayıt varlık kontrolü - `belongsToMany`: Pivot tablo varlık kontrolü - `morphTo`: Polimorfik ilişki varlık kontrolü
Referans ¶
Detaylı bilgi için bkz: `docs/Relationships.md`
func NewRelationshipExistence ¶
func NewRelationshipExistence(field RelationshipField) *RelationshipExistenceImpl
NewRelationshipExistence, yeni bir relationship varlık kontrolcüsü oluşturur.
Bu constructor, verilen relationship field için varlık kontrolü yapabilen bir handler oluşturur. Handler, ilişki tipine göre otomatik olarak uygun EXISTS sorgu stratejisini seçer.
Parametreler ¶
- `field`: Varlık kontrolü yapılacak relationship field (RelationshipField interface'ini implement etmeli)
Dönüş Değerleri ¶
- `*RelationshipExistenceImpl`: Yapılandırılmış varlık kontrolcüsü pointer'ı
Kullanım Örneği ¶
```go // BelongsTo ilişkisi için authorField := fields.NewBelongsTo("author", "Author") existence := fields.NewRelationshipExistence(authorField)
// HasMany ilişkisi için commentsField := fields.NewHasMany("comments", "Comment") existence := fields.NewRelationshipExistence(commentsField)
// BelongsToMany ilişkisi için tagsField := fields.NewBelongsToMany("tags", "Tag") existence := fields.NewRelationshipExistence(tagsField) ```
Notlar ¶
- Field parametresi nil olmamalıdır - Field, RelationshipField interface'ini implement etmelidir - Döndürülen handler thread-safe değildir, concurrent kullanım için senkronizasyon gerekir
Referans ¶
Detaylı bilgi için bkz: `docs/Relationships.md`
func (*RelationshipExistenceImpl) DoesntExist ¶
func (re *RelationshipExistenceImpl) DoesntExist(ctx context.Context) (bool, error)
DoesntExist, hiç ilişkili kaynak bulunmadığını kontrol eder.
Bu method, `Exists` metodunun tersini döndürür. İlişkili hiç kaynak yoksa `true`, en az bir ilişkili kaynak varsa `false` döner.
Parametreler ¶
- `ctx`: Context nesnesi (timeout, cancellation için)
Dönüş Değerleri ¶
- `bool`: Hiç ilişkili kaynak yoksa `true`, varsa `false` - `error`: Kontrol sırasında oluşan hata, başarılıysa `nil`
Davranış ¶
Bu method dahili olarak `Exists` metodunu çağırır ve sonucunu tersine çevirir: - `Exists` true dönerse -> `DoesntExist` false döner - `Exists` false dönerse -> `DoesntExist` true döner - `Exists` hata dönerse -> `DoesntExist` de aynı hatayı döner
Kullanım Örneği ¶
```go // BelongsTo ilişkisi için authorField := fields.NewBelongsTo("author", "Author") existence := fields.NewRelationshipExistence(authorField)
noAuthor, err := existence.DoesntExist(context.Background())
if err != nil {
return fmt.Errorf("varlık kontrolü başarısız: %w", err)
}
if noAuthor {
fmt.Println("Yazar atanmamış")
} else {
fmt.Println("Yazar mevcut")
}
// HasMany ilişkisi için - yorum kontrolü commentsField := fields.NewHasMany("comments", "Comment") existence := fields.NewRelationshipExistence(commentsField)
noComments, err := existence.DoesntExist(ctx)
if err != nil {
return err
}
if noComments {
fmt.Println("Henüz yorum yapılmamış")
}
// Validation senaryosu
if noComments {
return errors.New("en az bir yorum gerekli")
}
```
Notlar ¶
- Context timeout veya cancellation durumunda hata döner - `Exists` metodunun tüm davranışları geçerlidir - Database bağlantı hataları error olarak döner - Bu method thread-safe değildir - Validation ve conditional logic için idealdir
Referans ¶
Detaylı bilgi için bkz: `docs/Relationships.md`
func (*RelationshipExistenceImpl) Exists ¶
func (re *RelationshipExistenceImpl) Exists(ctx context.Context) (bool, error)
Exists, ilişkili kaynakların var olup olmadığını kontrol eder.
Bu method, relationship field'ın tipine göre otomatik olarak uygun EXISTS sorgu stratejisini seçer ve çalıştırır. Her ilişki tipi için özel kontrol mantığı uygulanır.
Parametreler ¶
- `ctx`: Context nesnesi (timeout, cancellation için)
Dönüş Değerleri ¶
- `bool`: İlişkili kaynak varsa `true`, yoksa `false` - `error`: Kontrol sırasında oluşan hata, başarılıysa `nil`
İlişki Tiplerine Göre Davranış ¶
- `belongsTo`: Foreign key üzerinden parent kaynak varlığını kontrol eder - `hasMany`: Child kayıtların varlığını kontrol eder (COUNT > 0) - `hasOne`: Child kaydın varlığını kontrol eder - `belongsToMany`: Pivot tablo üzerinden ilişki varlığını kontrol eder - `morphTo`: Polimorfik ilişki varlığını kontrol eder (type ve id üzerinden)
Kullanım Örneği ¶
```go // BelongsTo ilişkisi için authorField := fields.NewBelongsTo("author", "Author") existence := fields.NewRelationshipExistence(authorField)
exists, err := existence.Exists(context.Background())
if err != nil {
return fmt.Errorf("varlık kontrolü başarısız: %w", err)
}
if exists {
fmt.Println("Yazar kaydı mevcut")
} else {
fmt.Println("Yazar kaydı bulunamadı")
}
// HasMany ilişkisi için commentsField := fields.NewHasMany("comments", "Comment") existence := fields.NewRelationshipExistence(commentsField)
hasComments, err := existence.Exists(ctx)
if err != nil {
return err
}
if hasComments {
fmt.Println("En az bir yorum var")
}
```
Notlar ¶
- Context timeout veya cancellation durumunda hata döner - Bilinmeyen ilişki tipleri için `false, nil` döner - Database bağlantı hataları error olarak döner - Bu method thread-safe değildir
Referans ¶
Detaylı bilgi için bkz: `docs/Relationships.md`
type RelationshipField ¶
type RelationshipField interface {
Element
// GetRelationshipType, ilişki türünü döndürür.
// Döndürür: "belongsTo", "hasMany", "hasOne", "belongsToMany", "morphTo"
GetRelationshipType() string
// GetRelatedResourceSlug, ilgili resource'un slug'ını döndürür.
// Döndürür: İlgili resource'un benzersiz tanımlayıcısı (slug)
GetRelatedResourceSlug() string
// GetRelationshipName, ilişkinin adını döndürür.
// Döndürür: İlişkinin adı (örn. "author", "posts", "roles")
GetRelationshipName() string
// ResolveRelationship, verilen item için ilişkili verileri çözümler.
// Parametreler:
// - item: İlişkili verileri çözümlenecek kaynak
// Döndürür:
// - İlişkili veriler (tek kayıt veya kayıt listesi)
// - Hata (çözümleme başarısız olursa)
ResolveRelationship(item interface{}) (interface{}, error)
// GetQueryCallback, sorgu özelleştirme callback'ini döndürür.
// Döndürür: Sorguyu özelleştiren callback fonksiyonu
GetQueryCallback() func(interface{}) interface{}
// GetLoadingStrategy, yükleme stratejisini döndürür.
// Döndürür: EAGER_LOADING veya LAZY_LOADING
GetLoadingStrategy() LoadingStrategy
// ValidateRelationship, ilişki değerini doğrular.
// Parametreler:
// - value: Doğrulanacak değer
// Döndürür:
// - Hata (doğrulama başarısız olursa)
ValidateRelationship(value interface{}) error
// GetDisplayKey, BelongsTo için görüntülenecek key'i döndürür.
// Döndürür: Görüntüleme için kullanılacak alan adı (örn. "name", "title")
GetDisplayKey() string
// GetSearchableColumns, BelongsTo için aranabilir sütunları döndürür.
// Döndürür: Aranabilir sütun adlarının listesi
GetSearchableColumns() []string
// IsRequired, ilişkinin zorunlu olup olmadığını döndürür.
// Döndürür: true ise ilişki zorunludur
IsRequired() bool
// GetTypes, MorphTo için kullanılabilir tipleri döndürür.
// Döndürür: Tip adı -> resource slug eşlemesi
GetTypes() map[string]string
}
RelationshipField, alan sisteminde bir veritabanı ilişkisini temsil eder.
Bu interface, tüm ilişki türleri (BelongsTo, HasMany, HasOne, BelongsToMany, MorphTo) için ortak metodları tanımlar.
Temel Özellikler ¶
- **Tip Bilgisi**: İlişki türünü ve ilgili resource'u belirtir - **Çözümleme**: İlişkili verileri yükler ve çözümler - **Sorgu Özelleştirme**: İlişki sorgularını özelleştirme callback'leri - **Yükleme Stratejisi**: Eager veya lazy loading seçimi - **Doğrulama**: İlişki verilerini doğrulama - **Görüntüleme**: İlişkili verilerin nasıl gösterileceğini kontrol eder
Kullanım ¶
RelationshipField interface'i doğrudan kullanılmaz, bunun yerine BelongsTo, HasMany, HasOne, BelongsToMany, MorphTo gibi somut tipler kullanılır.
Daha fazla bilgi için docs/Relationships.md dosyasına bakın.
func IsRelationshipField ¶
func IsRelationshipField(e Element) (RelationshipField, bool)
IsRelationshipField checks if an element is a relationship field
Bu fonksiyon, bir element'in relationship field olup olmadığını kontrol eder. core.Element interface'i RelationshipField interface'ini embed etmediği için, direkt type assertion yerine view field'ına bakarak kontrol yaparız.
Relationship field view'ları: - "has-many-field": HasMany ilişkisi - "belongs-to-field": BelongsTo ilişkisi - "has-one-field": HasOne ilişkisi - "morph-to-field": MorphTo ilişkisi - "morph-to-many-field": MorphToMany ilişkisi - "belongs-to-many-field": BelongsToMany ilişkisi
type RelationshipFilter ¶
type RelationshipFilter interface {
// ApplyFilter, ilişki sorgusuna bir filtre uygular
ApplyFilter(ctx context.Context, column string, operator string, value interface{}) ([]interface{}, error)
// ApplyMultipleFilters, birden fazla filtre uygular
ApplyMultipleFilters(ctx context.Context, filters map[string]interface{}) ([]interface{}, error)
// RemoveFilter, filtreyi kaldırır ve tüm ilişkili kaynakları yükler
RemoveFilter(ctx context.Context) ([]interface{}, error)
}
RelationshipFilter, ilişkiler için filtreleme işlevselliğini yönetir.
Bu interface, ilişkili kayıtları filtrelemek için metodlar sağlar. Tek veya çoklu filtreler uygulanabilir.
Kullanım Örneği ¶
filter := fields.NewRelationshipFilter(field) results, err := filter.ApplyFilter(ctx, "status", "=", "active")
Daha fazla bilgi için docs/Relationships.md dosyasına bakın.
type RelationshipFilterImpl ¶
type RelationshipFilterImpl struct {
// contains filtered or unexported fields
}
RelationshipFilterImpl, RelationshipFilter interface'ini implement eder.
Bu yapı, ilişki filtreleme işlemlerini gerçekleştirir. Filtreler saklanır ve sorguya uygulanır.
func NewRelationshipFilter ¶
func NewRelationshipFilter(field RelationshipField) *RelationshipFilterImpl
NewRelationshipFilter, yeni bir relationship filter handler oluşturur.
Bu fonksiyon, verilen field için filtreleme handler'ı döndürür.
Parametreler ¶
- **field**: İlişki field'ı
Kullanım Örneği ¶
filter := fields.NewRelationshipFilter(field)
Döndürür:
- Yapılandırılmış RelationshipFilterImpl pointer'ı
func (*RelationshipFilterImpl) ApplyFilter ¶
func (rf *RelationshipFilterImpl) ApplyFilter(ctx context.Context, column string, operator string, value interface{}) ([]interface{}, error)
ApplyFilter applies a filter to the relationship query
func (*RelationshipFilterImpl) ApplyMultipleFilters ¶
func (rf *RelationshipFilterImpl) ApplyMultipleFilters(ctx context.Context, filters map[string]interface{}) ([]interface{}, error)
ApplyMultipleFilters applies multiple filters
func (*RelationshipFilterImpl) GetFilters ¶
func (rf *RelationshipFilterImpl) GetFilters() map[string]interface{}
GetFilters returns the current filters
func (*RelationshipFilterImpl) RemoveFilter ¶
func (rf *RelationshipFilterImpl) RemoveFilter(ctx context.Context) ([]interface{}, error)
RemoveFilter removes a filter and loads all related resources
type RelationshipGormConfig ¶
type RelationshipGormConfig struct {
// Foreign Key Yapılandırması (BelongsTo, HasOne, HasMany)
ForeignKey string `json:"-"` // Foreign key sütun adı (örn: "author_id")
References string `json:"-"` // Referans sütun (örn: "id")
OnDelete string `json:"-"` // ON DELETE davranışı: CASCADE, SET NULL, RESTRICT, NO ACTION
OnUpdate string `json:"-"` // ON UPDATE davranışı
ConstraintName string `json:"-"` // Özel constraint adı
// Many-to-Many Yapılandırması (BelongsToMany)
PivotTable string `json:"-"` // Ara tablo adı (örn: "user_roles")
JoinForeignKey string `json:"-"` // Join tablosundaki ana model FK (örn: "user_id")
JoinReferences string `json:"-"` // Join tablosundaki referans FK (örn: "role_id")
JoinTable string `json:"-"` // GORM joinTable alias
// Polymorphic Yapılandırması (MorphTo, MorphOne, MorphMany, MorphToMany)
Polymorphic bool `json:"-"` // Polymorphic ilişki mi?
PolymorphicType string `json:"-"` // Type sütun adı (örn: "commentable_type")
PolymorphicID string `json:"-"` // ID sütun adı (örn: "commentable_id")
PolymorphicValue string `json:"-"` // Type değeri (örn: "posts", "users")
// Eager Loading
Preload bool `json:"-"` // Otomatik preload yapılsın mı?
}
RelationshipGormConfig, ilişki field'ları için GORM yapılandırmasını tanımlar. Bu yapı, foreign key, pivot tablo ve polymorphic ilişkiler için kullanılır.
func NewRelationshipGormConfig ¶
func NewRelationshipGormConfig() *RelationshipGormConfig
NewRelationshipGormConfig, varsayılan değerlerle yeni bir RelationshipGormConfig oluşturur.
func (*RelationshipGormConfig) ToForeignKeyTag ¶
func (r *RelationshipGormConfig) ToForeignKeyTag() string
ToForeignKeyTag, foreign key sütunu için GORM tag oluşturur. BelongsTo ilişkilerinde kullanılır (örn: author_id uint `gorm:"index"`).
func (*RelationshipGormConfig) ToGormTag ¶
func (r *RelationshipGormConfig) ToGormTag() string
ToGormTag, ilişki için GORM struct tag'ini oluşturur. Bu metod, model alanları için gorm tag'leri üretir.
func (*RelationshipGormConfig) WithConstraintName ¶
func (r *RelationshipGormConfig) WithConstraintName(name string) *RelationshipGormConfig
WithConstraintName, özel constraint adı belirler.
func (*RelationshipGormConfig) WithForeignKey ¶
func (r *RelationshipGormConfig) WithForeignKey(fk string) *RelationshipGormConfig
WithForeignKey, foreign key sütununu belirler.
func (*RelationshipGormConfig) WithOnDelete ¶
func (r *RelationshipGormConfig) WithOnDelete(action string) *RelationshipGormConfig
WithOnDelete, ON DELETE davranışını belirler.
func (*RelationshipGormConfig) WithOnUpdate ¶
func (r *RelationshipGormConfig) WithOnUpdate(action string) *RelationshipGormConfig
WithOnUpdate, ON UPDATE davranışını belirler.
func (*RelationshipGormConfig) WithPivotTable ¶
func (r *RelationshipGormConfig) WithPivotTable(table, joinFK, joinRef string) *RelationshipGormConfig
WithPivotTable, many-to-many için ara tablo belirler.
func (*RelationshipGormConfig) WithPolymorphic ¶
func (r *RelationshipGormConfig) WithPolymorphic(typeColumn, idColumn string) *RelationshipGormConfig
WithPolymorphic, polymorphic ilişki yapılandırır.
func (*RelationshipGormConfig) WithPolymorphicValue ¶
func (r *RelationshipGormConfig) WithPolymorphicValue(value string) *RelationshipGormConfig
WithPolymorphicValue, polymorphic type değerini belirler.
func (*RelationshipGormConfig) WithPreload ¶
func (r *RelationshipGormConfig) WithPreload(enabled bool) *RelationshipGormConfig
WithPreload, eager loading'i etkinleştirir/devre dışı bırakır.
func (*RelationshipGormConfig) WithReferences ¶
func (r *RelationshipGormConfig) WithReferences(ref string) *RelationshipGormConfig
WithReferences, referans sütununu belirler.
type RelationshipLoader ¶
type RelationshipLoader interface {
// Load related data using eager loading strategy
EagerLoad(ctx context.Context, items []interface{}, field RelationshipField) error
// Load related data using lazy loading strategy
LazyLoad(ctx context.Context, item interface{}, field RelationshipField) (interface{}, error)
// Load with constraints applied
LoadWithConstraints(ctx context.Context, item interface{}, field RelationshipField, constraints map[string]interface{}) (interface{}, error)
}
RelationshipLoader handles loading relationships with different strategies
type RelationshipLoaderImpl ¶
type RelationshipLoaderImpl struct {
}
RelationshipLoaderImpl, RelationshipLoader interface'ini implement eder.
Bu yapı, ilişki yükleme işlemlerini gerçekleştirir. Eager loading ve lazy loading stratejilerini destekler.
Kullanım Örneği ¶
loader := fields.NewRelationshipLoader() err := loader.EagerLoad(ctx, items, field)
Daha fazla bilgi için docs/Relationships.md dosyasına bakın.
func NewRelationshipLoader ¶
func NewRelationshipLoader() *RelationshipLoaderImpl
NewRelationshipLoader, yeni bir relationship loader oluşturur.
Bu fonksiyon, ilişki yükleme işlemleri için loader döndürür.
Kullanım Örneği ¶
loader := fields.NewRelationshipLoader()
Döndürür:
- Yapılandırılmış RelationshipLoaderImpl pointer'ı
func (*RelationshipLoaderImpl) EagerLoad ¶
func (rl *RelationshipLoaderImpl) EagerLoad(ctx context.Context, items []interface{}, field RelationshipField) error
EagerLoad, eager loading stratejisi kullanarak ilişkili verileri yükler.
Bu metod, tüm ilişkili verileri tek bir sorguda yükler. N+1 sorgu problemini önlemek için kullanılır.
Parametreler ¶
- **ctx**: Context - **items**: Yüklenecek öğeler - **field**: İlişki field'ı
Kullanım Örneği ¶
err := loader.EagerLoad(ctx, items, field)
Döndürür:
- Hata (yükleme başarısız olursa)
func (*RelationshipLoaderImpl) LazyLoad ¶
func (rl *RelationshipLoaderImpl) LazyLoad(ctx context.Context, item interface{}, field RelationshipField) (interface{}, error)
LazyLoad loads related data using lazy loading strategy This loads related data on demand
func (*RelationshipLoaderImpl) LoadWithConstraints ¶
func (rl *RelationshipLoaderImpl) LoadWithConstraints(ctx context.Context, item interface{}, field RelationshipField, constraints map[string]interface{}) (interface{}, error)
LoadWithConstraints loads related data with constraints applied
type RelationshipPagination ¶
type RelationshipPagination interface {
// ApplyPagination, ilişki sorgusuna sayfalama uygular.
//
// # Parametreler
//
// - ctx: Context nesnesi
// - page: Sayfa numarası (minimum 1, geçersiz değerler 1'e ayarlanır)
// - perPage: Sayfa başına kayıt sayısı (minimum 1, maksimum 100)
//
// # Dönüş Değerleri
//
// - []interface{}: Sayfalanmış kayıt listesi
// - error: Hata durumunda hata nesnesi
//
// # Önemli Notlar
//
// - Sayfa numarası 1'den küçükse otomatik olarak 1'e ayarlanır
// - Sayfa boyutu 1'den küçükse otomatik olarak 15'e ayarlanır
// - Sayfa boyutu 100'den büyükse otomatik olarak 100'e sınırlanır
ApplyPagination(ctx context.Context, page int, perPage int) ([]interface{}, error)
// GetPageInfo, sayfalama metadata'sını döndürür.
//
// # Dönüş Değeri
//
// Map içeriği:
// - current_page: Mevcut sayfa numarası
// - per_page: Sayfa başına kayıt sayısı
// - total: Toplam kayıt sayısı
// - total_pages: Toplam sayfa sayısı
// - from: Başlangıç kayıt indeksi
// - to: Bitiş kayıt indeksi
//
// # Kullanım Örneği
//
// info := pagination.GetPageInfo()
// currentPage := info["current_page"].(int)
// totalPages := info["total_pages"].(int64)
GetPageInfo() map[string]interface{}
}
RelationshipPagination, ilişkiler için sayfalama işlevselliğini yönetir.
Bu interface, ilişkili kayıtları sayfalamak için metodlar sağlar. Sayfa numarası ve sayfa boyutu belirlenebilir, sayfalama metadata'sı alınabilir.
Kullanım Örneği ¶
pagination := fields.NewRelationshipPagination(field)
results, err := pagination.ApplyPagination(ctx, 1, 15)
if err != nil {
log.Fatal(err)
}
pageInfo := pagination.GetPageInfo()
Daha fazla bilgi için docs/Relationships.md dosyasına bakın.
type RelationshipPaginationImpl ¶
type RelationshipPaginationImpl struct {
// contains filtered or unexported fields
}
RelationshipPaginationImpl, RelationshipPagination interface'ini uygular.
Bu struct, ilişki sayfalama işlemlerinin somut implementasyonunu sağlar. Sayfa numarası, sayfa boyutu ve toplam kayıt sayısı bilgilerini tutar.
Alanlar ¶
- field: İlişki alanı referansı
- page: Mevcut sayfa numarası (varsayılan: 1)
- perPage: Sayfa başına kayıt sayısı (varsayılan: 15)
- total: Toplam kayıt sayısı (varsayılan: 0)
Kullanım Örneği ¶
impl := &RelationshipPaginationImpl{
field: myField,
page: 1,
perPage: 20,
total: 100,
}
Daha fazla bilgi için docs/Relationships.md dosyasına bakın.
func NewRelationshipPagination ¶
func NewRelationshipPagination(field RelationshipField) *RelationshipPaginationImpl
NewRelationshipPagination, yeni bir ilişki sayfalama yöneticisi oluşturur.
Bu constructor, varsayılan değerlerle yapılandırılmış bir sayfalama nesnesi döndürür. Sayfa numarası 1, sayfa boyutu 15 ve toplam kayıt sayısı 0 olarak başlatılır.
Parametreler ¶
- field: İlişki alanı (RelationshipField interface'ini uygulayan nesne)
Dönüş Değeri ¶
- *RelationshipPaginationImpl: Yapılandırılmış sayfalama nesnesi pointer'ı
Kullanım Örneği ¶
field := fields.NewBelongsTo("user", "User")
pagination := fields.NewRelationshipPagination(field)
// pagination.page = 1, pagination.perPage = 15, pagination.total = 0
Varsayılan Değerler ¶
- Sayfa numarası: 1
- Sayfa boyutu: 15
- Toplam kayıt: 0
Daha fazla bilgi için docs/Relationships.md dosyasına bakın.
func (*RelationshipPaginationImpl) ApplyPagination ¶
func (rp *RelationshipPaginationImpl) ApplyPagination(ctx context.Context, page int, perPage int) ([]interface{}, error)
ApplyPagination, ilişki sorgusuna sayfalama uygular.
Bu metod, sayfa numarası ve sayfa boyutunu doğrular, geçersiz değerleri düzeltir ve sayfalama parametrelerini ayarlar. Sayfa boyutu maksimum 100 ile sınırlandırılır.
Parametreler ¶
- ctx: Context nesnesi (iptal ve timeout yönetimi için)
- page: Sayfa numarası (minimum 1, geçersiz değerler 1'e ayarlanır)
- perPage: Sayfa başına kayıt sayısı (minimum 1, maksimum 100)
Dönüş Değerleri ¶
- []interface{}: Sayfalanmış kayıt listesi
- error: Hata durumunda hata nesnesi, başarılı ise nil
Doğrulama Kuralları ¶
- page < 1 ise otomatik olarak 1'e ayarlanır
- perPage < 1 ise otomatik olarak 15'e ayarlanır
- perPage > 100 ise otomatik olarak 100'e sınırlanır
Kullanım Örneği ¶
pagination := fields.NewRelationshipPagination(field)
results, err := pagination.ApplyPagination(ctx, 2, 20)
if err != nil {
log.Fatal(err)
}
// results içinde 2. sayfanın 20 kaydı bulunur
Önemli Notlar ¶
- Şu anki implementasyon boş slice döndürür (placeholder)
- Gerçek implementasyonda LIMIT ve OFFSET ile veritabanı sorgusu yapılır
- Sayfa boyutu güvenlik nedeniyle 100 ile sınırlandırılmıştır
Daha fazla bilgi için docs/Relationships.md dosyasına bakın.
func (*RelationshipPaginationImpl) GetPage ¶
func (rp *RelationshipPaginationImpl) GetPage() int
GetPage, mevcut sayfa numarasını döndürür.
Bu metod, ApplyPagination() ile ayarlanan veya varsayılan sayfa numarasını döndürür.
Dönüş Değeri ¶
- int: Mevcut sayfa numarası (minimum 1)
Kullanım Örneği ¶
pagination := fields.NewRelationshipPagination(field) fmt.Println(pagination.GetPage()) // Çıktı: 1 (varsayılan) pagination.ApplyPagination(ctx, 3, 15) fmt.Println(pagination.GetPage()) // Çıktı: 3
Önemli Notlar ¶
- Varsayılan değer 1'dir (NewRelationshipPagination ile oluşturulduğunda)
- ApplyPagination() çağrıldıktan sonra güncellenir
Daha fazla bilgi için docs/Relationships.md dosyasına bakın.
func (*RelationshipPaginationImpl) GetPageInfo ¶
func (rp *RelationshipPaginationImpl) GetPageInfo() map[string]interface{}
GetPageInfo, sayfalama metadata'sını döndürür.
Bu metod, mevcut sayfalama durumu hakkında detaylı bilgi içeren bir map döndürür. Toplam sayfa sayısı, mevcut sayfa, kayıt aralıkları gibi bilgiler içerir.
Dönüş Değeri ¶
Map içeriği:
- current_page (int): Mevcut sayfa numarası
- per_page (int): Sayfa başına kayıt sayısı
- total (int64): Toplam kayıt sayısı
- total_pages (int64): Toplam sayfa sayısı
- from (int): Başlangıç kayıt indeksi (0-based)
- to (int): Bitiş kayıt indeksi (0-based)
Kullanım Örneği ¶
pagination := fields.NewRelationshipPagination(field)
pagination.SetTotal(100)
pagination.ApplyPagination(ctx, 2, 15)
info := pagination.GetPageInfo()
fmt.Printf("Sayfa %d/%d\n", info["current_page"], info["total_pages"])
fmt.Printf("Kayıt %d-%d / %d\n", info["from"], info["to"], info["total"])
// Çıktı: Sayfa 2/7
// Çıktı: Kayıt 15-30 / 100
Hesaplama Detayları ¶
- total_pages = ceil(total / perPage)
- from = (current_page - 1) * perPage
- to = current_page * perPage
Önemli Notlar ¶
- perPage 0 ise total_pages 0 olarak döner (sıfıra bölme hatası önlenir)
- from ve to değerleri 0-based indeks kullanır
- SetTotal() ile toplam kayıt sayısı ayarlanmalıdır
Daha fazla bilgi için docs/Relationships.md dosyasına bakın.
func (*RelationshipPaginationImpl) GetPerPage ¶
func (rp *RelationshipPaginationImpl) GetPerPage() int
GetPerPage, sayfa başına kayıt sayısını döndürür.
Bu metod, ApplyPagination() ile ayarlanan veya varsayılan sayfa boyutunu döndürür.
Dönüş Değeri ¶
- int: Sayfa başına kayıt sayısı (minimum 1, maksimum 100)
Kullanım Örneği ¶
pagination := fields.NewRelationshipPagination(field) fmt.Println(pagination.GetPerPage()) // Çıktı: 15 (varsayılan) pagination.ApplyPagination(ctx, 1, 25) fmt.Println(pagination.GetPerPage()) // Çıktı: 25 pagination.ApplyPagination(ctx, 1, 150) fmt.Println(pagination.GetPerPage()) // Çıktı: 100 (maksimum sınır)
Önemli Notlar ¶
- Varsayılan değer 15'tir (NewRelationshipPagination ile oluşturulduğunda)
- ApplyPagination() çağrıldıktan sonra güncellenir
- Değer otomatik olarak 1-100 aralığında sınırlandırılır
Daha fazla bilgi için docs/Relationships.md dosyasına bakın.
func (*RelationshipPaginationImpl) GetTotal ¶
func (rp *RelationshipPaginationImpl) GetTotal() int64
GetTotal, toplam kayıt sayısını döndürür.
Bu metod, SetTotal() ile ayarlanan toplam kayıt sayısını döndürür. Sayfalama metadata hesaplamaları için kullanılır.
Dönüş Değeri ¶
- int64: Toplam kayıt sayısı
Kullanım Örneği ¶
pagination := fields.NewRelationshipPagination(field) fmt.Println(pagination.GetTotal()) // Çıktı: 0 (varsayılan) pagination.SetTotal(250) fmt.Println(pagination.GetTotal()) // Çıktı: 250 // Toplam sayfa sayısını hesapla totalPages := (pagination.GetTotal() + int64(pagination.GetPerPage()) - 1) / int64(pagination.GetPerPage()) fmt.Println(totalPages) // Çıktı: 17 (ceil(250/15))
Önemli Notlar ¶
- Varsayılan değer 0'dır (NewRelationshipPagination ile oluşturulduğunda)
- SetTotal() ile güncellenir
- GetPageInfo() bu değeri kullanarak total_pages hesaplar
Daha fazla bilgi için docs/Relationships.md dosyasına bakın.
func (*RelationshipPaginationImpl) SetTotal ¶
func (rp *RelationshipPaginationImpl) SetTotal(total int64)
SetTotal, toplam kayıt sayısını ayarlar.
Bu metod, sayfalama hesaplamaları için gerekli olan toplam kayıt sayısını belirler. GetPageInfo() metodunun doğru sonuçlar döndürebilmesi için bu metod çağrılmalıdır.
Parametreler ¶
- total: Toplam kayıt sayısı (int64)
Kullanım Örneği ¶
pagination := fields.NewRelationshipPagination(field) pagination.SetTotal(150) // 150 kayıt var pagination.ApplyPagination(ctx, 1, 20) info := pagination.GetPageInfo() // info["total"] = 150 // info["total_pages"] = 8 (ceil(150/20))
Önemli Notlar ¶
- Bu metod ApplyPagination() çağrılmadan önce veya sonra çağrılabilir
- Toplam kayıt sayısı genellikle veritabanı COUNT sorgusu ile elde edilir
- Negatif değerler kabul edilir ancak mantıksal olarak 0 veya pozitif olmalıdır
Daha fazla bilgi için docs/Relationships.md dosyasına bakın.
type RelationshipQuery ¶
type RelationshipQuery interface {
// Apply WHERE clause
Where(column string, operator string, value interface{}) RelationshipQuery
// Apply WHERE IN clause
WhereIn(column string, values []interface{}) RelationshipQuery
// Apply ORDER BY clause
OrderBy(column string, direction string) RelationshipQuery
// Apply LIMIT clause
Limit(limit int) RelationshipQuery
// Apply OFFSET clause
Offset(offset int) RelationshipQuery
// Get count of results
Count(ctx context.Context) (int64, error)
// Check if results exist
Exists(ctx context.Context) (bool, error)
// Execute query and get results
Get(ctx context.Context) ([]interface{}, error)
// Execute query and get first result
First(ctx context.Context) (interface{}, error)
}
RelationshipQuery represents a query builder for relationships
type RelationshipQueryImpl ¶
type RelationshipQueryImpl struct {
// contains filtered or unexported fields
}
RelationshipQueryImpl, RelationshipQuery interface'ini implement eder.
Bu yapı, ilişki sorguları için query builder sağlar. WHERE, ORDER BY, LIMIT, OFFSET gibi SQL clause'larını destekler.
Kullanım Örneği ¶
query := fields.NewRelationshipQuery().
Where("status", "=", "active").
OrderBy("created_at", "DESC").
Limit(10)
Daha fazla bilgi için docs/Relationships.md dosyasına bakın.
func NewRelationshipQuery ¶
func NewRelationshipQuery() *RelationshipQueryImpl
NewRelationshipQuery, yeni bir relationship query oluşturur.
Bu fonksiyon, ilişki sorguları için boş bir query builder döndürür. Query builder, method chaining ile sorgu oluşturmayı destekler.
Kullanım Örneği ¶
query := fields.NewRelationshipQuery()
Döndürür:
- Yapılandırılmış RelationshipQueryImpl pointer'ı
func (*RelationshipQueryImpl) Count ¶
func (rq *RelationshipQueryImpl) Count(ctx context.Context) (int64, error)
Count gets count of results
func (*RelationshipQueryImpl) Exists ¶
func (rq *RelationshipQueryImpl) Exists(ctx context.Context) (bool, error)
Exists checks if results exist
func (*RelationshipQueryImpl) First ¶
func (rq *RelationshipQueryImpl) First(ctx context.Context) (interface{}, error)
First executes query and gets first result
func (*RelationshipQueryImpl) Get ¶
func (rq *RelationshipQueryImpl) Get(ctx context.Context) ([]interface{}, error)
Get executes query and gets results
func (*RelationshipQueryImpl) GetLimit ¶
func (rq *RelationshipQueryImpl) GetLimit() int
GetLimit returns the LIMIT value
func (*RelationshipQueryImpl) GetOffset ¶
func (rq *RelationshipQueryImpl) GetOffset() int
GetOffset returns the OFFSET value
func (*RelationshipQueryImpl) GetOrderByColumns ¶
func (rq *RelationshipQueryImpl) GetOrderByColumns() []map[string]interface{}
GetOrderByColumns returns the ORDER BY columns
func (*RelationshipQueryImpl) GetWhereConditions ¶
func (rq *RelationshipQueryImpl) GetWhereConditions() []map[string]interface{}
GetWhereConditions returns the WHERE conditions
func (*RelationshipQueryImpl) Limit ¶
func (rq *RelationshipQueryImpl) Limit(limit int) RelationshipQuery
Limit applies LIMIT clause
func (*RelationshipQueryImpl) Offset ¶
func (rq *RelationshipQueryImpl) Offset(offset int) RelationshipQuery
Offset applies OFFSET clause
func (*RelationshipQueryImpl) OrderBy ¶
func (rq *RelationshipQueryImpl) OrderBy(column string, direction string) RelationshipQuery
OrderBy applies ORDER BY clause
func (*RelationshipQueryImpl) String ¶
func (rq *RelationshipQueryImpl) String() string
String returns a string representation of the query
func (*RelationshipQueryImpl) Where ¶
func (rq *RelationshipQueryImpl) Where(column string, operator string, value interface{}) RelationshipQuery
Where applies WHERE clause
func (*RelationshipQueryImpl) WhereIn ¶
func (rq *RelationshipQueryImpl) WhereIn(column string, values []interface{}) RelationshipQuery
WhereIn applies WHERE IN clause
type RelationshipSearch ¶
type RelationshipSearch interface {
// Search, terime göre ilişkili kaynakları arar
Search(ctx context.Context, term string) ([]interface{}, error)
// SearchInColumns, belirli sütunlarda arama yapar
SearchInColumns(ctx context.Context, term string, columns []string) ([]interface{}, error)
// GetSearchableColumns, aranabilir sütunları döndürür
GetSearchableColumns() []string
}
RelationshipSearch, ilişkiler için arama işlevselliğini yönetir.
Bu interface, ilişkili kayıtlarda arama yapmak için metodlar sağlar. Belirli sütunlarda veya tüm aranabilir sütunlarda arama yapılabilir.
Kullanım Örneği ¶
search := fields.NewRelationshipSearch(field) results, err := search.Search(ctx, "john")
Daha fazla bilgi için docs/Relationships.md dosyasına bakın.
type RelationshipSearchImpl ¶
type RelationshipSearchImpl struct {
// contains filtered or unexported fields
}
RelationshipSearchImpl, RelationshipSearch interface'ini implement eder.
Bu yapı, ilişki arama işlemlerini gerçekleştirir. Aranabilir sütunlar field'dan alınır.
func NewRelationshipSearch ¶
func NewRelationshipSearch(field RelationshipField) *RelationshipSearchImpl
NewRelationshipSearch, yeni bir relationship search handler oluşturur.
Bu fonksiyon, verilen field için arama handler'ı döndürür.
Parametreler ¶
- **field**: İlişki field'ı
Kullanım Örneği ¶
search := fields.NewRelationshipSearch(field)
Döndürür:
- Yapılandırılmış RelationshipSearchImpl pointer'ı
func (*RelationshipSearchImpl) CaseInsensitiveSearch ¶
func (rs *RelationshipSearchImpl) CaseInsensitiveSearch(ctx context.Context, term string) ([]interface{}, error)
CaseInsensitiveSearch performs case-insensitive search
func (*RelationshipSearchImpl) GetSearchableColumns ¶
func (rs *RelationshipSearchImpl) GetSearchableColumns() []string
GetSearchableColumns returns the searchable columns
func (*RelationshipSearchImpl) Search ¶
func (rs *RelationshipSearchImpl) Search(ctx context.Context, term string) ([]interface{}, error)
Search searches for related resources by term
func (*RelationshipSearchImpl) SearchInColumns ¶
func (rs *RelationshipSearchImpl) SearchInColumns(ctx context.Context, term string, columns []string) ([]interface{}, error)
SearchInColumns searches in specific columns
type RelationshipSerialization ¶
type RelationshipSerialization interface {
// SerializeRelationship, tekil bir ilişkiyi JSON formatına dönüştürür.
//
// # Parametreler
//
// - `item`: Serileştirilecek ilişki verisi (nil olabilir)
//
// # Döndürür
//
// - `map[string]interface{}`: Serileştirilmiş veri (type, name, resource, value içerir)
// - `error`: Hata durumunda hata mesajı
//
// # Örnek
//
// “`go
// data, err := serializer.SerializeRelationship(user)
// // Sonuç: {"type": "belongsTo", "name": "author", "resource": "users", "value": {...}}
// “`
SerializeRelationship(item interface{}) (map[string]interface{}, error)
// SerializeRelationships, çoklu ilişkileri JSON formatına dönüştürür.
//
// # Parametreler
//
// - `items`: Serileştirilecek ilişki verileri dizisi (nil veya boş olabilir)
//
// # Döndürür
//
// - `[]map[string]interface{}`: Serileştirilmiş veri dizisi
// - `error`: Hata durumunda hata mesajı
//
// # Örnek
//
// “`go
// items, err := serializer.SerializeRelationships(users)
// // Sonuç: [{"type": "hasMany", "name": "posts", "resource": "posts", "value": {...}}, ...]
// “`
SerializeRelationships(items []interface{}) ([]map[string]interface{}, error)
}
RelationshipSerialization, ilişkilerin JSON serileştirme işlemlerini yönetir.
Bu interface, relationship field'larının JSON formatına dönüştürülmesi için gerekli metodları tanımlar. Hem tekil hem de çoklu ilişkilerin serileştirmesini destekler.
Kullanım ¶
```go serializer := NewRelationshipSerialization(relationshipField)
// Tekil ilişki serileştirme data, err := serializer.SerializeRelationship(user)
if err != nil {
log.Fatal(err)
}
// Çoklu ilişki serileştirme items, err := serializer.SerializeRelationships(users)
if err != nil {
log.Fatal(err)
}
```
Referans ¶
Detaylı bilgi için: docs/Relationships.md(../../docs/Relationships.md)
type RelationshipSerializationImpl ¶
type RelationshipSerializationImpl struct {
// contains filtered or unexported fields
}
RelationshipSerializationImpl, RelationshipSerialization interface'ini implement eder.
Bu struct, relationship field'larının JSON serileştirme işlemlerini gerçekleştirir. İlişki tipini, adını ve ilgili resource bilgilerini içeren JSON çıktısı üretir.
Alanlar ¶
- `field`: Serileştirilecek relationship field
Örnek ¶
```go
impl := &RelationshipSerializationImpl{
field: belongsToField,
}
```
func NewRelationshipSerialization ¶
func NewRelationshipSerialization(field RelationshipField) *RelationshipSerializationImpl
NewRelationshipSerialization, yeni bir relationship serialization handler oluşturur.
Bu constructor, verilen relationship field için bir serileştirme handler'ı başlatır.
Parametreler ¶
- `field`: Serileştirilecek relationship field
Döndürür ¶
- Yapılandırılmış RelationshipSerializationImpl pointer'ı
Örnek ¶
```go belongsTo := fields.NewBelongsTo("author").
SetRelatedResource("users")
serializer := fields.NewRelationshipSerialization(belongsTo)
// Kullanım data, err := serializer.SerializeRelationship(user) ```
Notlar ¶
- Field parametresi nil olmamalıdır - Döndürülen handler tüm serileştirme metodlarını destekler
func (*RelationshipSerializationImpl) SerializeRelationship ¶
func (rs *RelationshipSerializationImpl) SerializeRelationship(item interface{}) (map[string]interface{}, error)
SerializeRelationship, tekil bir ilişkiyi JSON formatına dönüştürür.
Bu method, verilen ilişki verisini JSON-uyumlu bir map yapısına dönüştürür. İlişki tipi, adı, resource bilgisi ve değeri içeren bir yapı oluşturur.
Parametreler ¶
- `item`: Serileştirilecek ilişki verisi (nil olabilir)
Döndürür ¶
- `map[string]interface{}`: Serileştirilmiş veri yapısı
- `type`: İlişki tipi (belongsTo, hasMany, hasOne, belongsToMany, morphTo)
- `name`: İlişki adı
- `resource`: İlgili resource adı
- `value`: İlişki verisi (nil olabilir)
- `error`: Hata durumunda hata mesajı (şu an için her zaman nil)
Örnek ¶
```go serializer := NewRelationshipSerialization(belongsToField) data, err := serializer.SerializeRelationship(user) // Sonuç: { // "type": "belongsTo", // "name": "author", // "resource": "users", // "value": {...} // } ```
Notlar ¶
- Nil değerler için sadece `value: nil` içeren bir map döner - İlişki metadata'sı field'dan otomatik olarak alınır
func (*RelationshipSerializationImpl) SerializeRelationships ¶
func (rs *RelationshipSerializationImpl) SerializeRelationships(items []interface{}) ([]map[string]interface{}, error)
SerializeRelationships, çoklu ilişkileri JSON formatına dönüştürür.
Bu method, verilen ilişki verileri dizisini JSON-uyumlu map dizisine dönüştürür. Her bir ilişki için SerializeRelationship metodunu çağırır.
Parametreler ¶
- `items`: Serileştirilecek ilişki verileri dizisi (nil veya boş olabilir)
Döndürür ¶
- `[]map[string]interface{}`: Serileştirilmiş veri dizisi (boş dizi olabilir) - `error`: Herhangi bir item'ın serileştirmesinde hata oluşursa hata mesajı
Örnek ¶
```go serializer := NewRelationshipSerialization(hasManyField) items, err := serializer.SerializeRelationships(posts)
if err != nil {
log.Fatal(err)
}
// Sonuç: [ // {"type": "hasMany", "name": "posts", "resource": "posts", "value": {...}}, // {"type": "hasMany", "name": "posts", "resource": "posts", "value": {...}} // ] ```
Notlar ¶
- Nil veya boş dizi için boş slice döner (nil değil) - Her item için ayrı ayrı SerializeRelationship çağrılır - Herhangi bir item'da hata oluşursa işlem durur ve hata döner
func (*RelationshipSerializationImpl) ToJSON ¶
func (rs *RelationshipSerializationImpl) ToJSON(item interface{}) (string, error)
ToJSON, ilişkiyi JSON string formatına dönüştürür.
Bu method, SerializeRelationship metodunu kullanarak ilişkiyi önce map yapısına, ardından JSON string formatına dönüştürür.
Parametreler ¶
- `item`: JSON'a dönüştürülecek ilişki verisi (nil olabilir)
Döndürür ¶
- `string`: JSON formatında string (örn: `{"type":"belongsTo","name":"author",...}`) - `error`: Serileştirme veya JSON encoding hatası
Örnek ¶
```go serializer := NewRelationshipSerialization(belongsToField) jsonStr, err := serializer.ToJSON(user)
if err != nil {
log.Fatal(err)
}
fmt.Println(jsonStr) // Çıktı: {"type":"belongsTo","name":"author","resource":"users","value":{...}} ```
Notlar ¶
- İç içe SerializeRelationship ve json.Marshal çağrıları yapar - Her iki aşamada da hata oluşabilir - Nil değerler için `{"value":null}` formatında JSON döner
func (*RelationshipSerializationImpl) ToJSONArray ¶
func (rs *RelationshipSerializationImpl) ToJSONArray(items []interface{}) (string, error)
ToJSONArray, çoklu ilişkileri JSON array string formatına dönüştürür.
Bu method, SerializeRelationships metodunu kullanarak ilişkileri önce map dizisine, ardından JSON array string formatına dönüştürür.
Parametreler ¶
- `items`: JSON array'e dönüştürülecek ilişki verileri dizisi (nil veya boş olabilir)
Döndürür ¶
- `string`: JSON array formatında string (örn: `[{"type":"hasMany",...},{...}]`) - `error`: Serileştirme veya JSON encoding hatası
Örnek ¶
```go serializer := NewRelationshipSerialization(hasManyField) jsonStr, err := serializer.ToJSONArray(posts)
if err != nil {
log.Fatal(err)
}
fmt.Println(jsonStr) // Çıktı: [{"type":"hasMany","name":"posts","resource":"posts","value":{...}},...] ```
Notlar ¶
- İç içe SerializeRelationships ve json.Marshal çağrıları yapar - Her iki aşamada da hata oluşabilir - Nil veya boş dizi için `[]` formatında JSON döner - HasMany ve BelongsToMany ilişkileri için idealdir
type RelationshipSort ¶
type RelationshipSort interface {
// ApplySort, ilişki sorgusuna bir sıralama uygular
ApplySort(ctx context.Context, column string, direction string) ([]interface{}, error)
// ApplyMultipleSorts, birden fazla sıralama uygular
ApplyMultipleSorts(ctx context.Context, sorts map[string]string) ([]interface{}, error)
// RemoveSort, sıralamayı kaldırır ve varsayılan sıralama düzenini kullanır
RemoveSort(ctx context.Context) ([]interface{}, error)
}
RelationshipSort, ilişkiler için sıralama işlevselliğini yönetir.
Bu interface, ilişkili kayıtları sıralamak için metodlar sağlar. Tek veya çoklu sıralamalar uygulanabilir.
Kullanım Örneği ¶
sort := fields.NewRelationshipSort(field) results, err := sort.ApplySort(ctx, "created_at", "DESC")
Daha fazla bilgi için docs/Relationships.md dosyasına bakın.
type RelationshipSortImpl ¶
type RelationshipSortImpl struct {
// contains filtered or unexported fields
}
RelationshipSortImpl, RelationshipSort interface'ini implement eder.
Bu yapı, ilişki sıralama işlemlerini gerçekleştirir. Sıralamalar saklanır ve sorguya uygulanır.
func NewRelationshipSort ¶
func NewRelationshipSort(field RelationshipField) *RelationshipSortImpl
NewRelationshipSort, yeni bir relationship sort handler oluşturur.
Bu fonksiyon, verilen field için sıralama handler'ı döndürür.
Parametreler ¶
- **field**: İlişki field'ı
Kullanım Örneği ¶
sort := fields.NewRelationshipSort(field)
Döndürür:
- Yapılandırılmış RelationshipSortImpl pointer'ı
func (*RelationshipSortImpl) ApplyMultipleSorts ¶
func (rs *RelationshipSortImpl) ApplyMultipleSorts(ctx context.Context, sorts map[string]string) ([]interface{}, error)
ApplyMultipleSorts applies multiple sorts
func (*RelationshipSortImpl) ApplySort ¶
func (rs *RelationshipSortImpl) ApplySort(ctx context.Context, column string, direction string) ([]interface{}, error)
ApplySort applies a sort to the relationship query
func (*RelationshipSortImpl) GetSorts ¶
func (rs *RelationshipSortImpl) GetSorts() map[string]string
GetSorts returns the current sorts
func (*RelationshipSortImpl) RemoveSort ¶
func (rs *RelationshipSortImpl) RemoveSort(ctx context.Context) ([]interface{}, error)
RemoveSort removes a sort and uses default sort order
type RelationshipValidator ¶
type RelationshipValidator interface {
// Validate that related resource exists
ValidateExists(ctx context.Context, value interface{}, field RelationshipField) error
// Validate foreign key references
ValidateForeignKey(ctx context.Context, value interface{}, field RelationshipField) error
// Validate pivot table entries
ValidatePivot(ctx context.Context, value interface{}, field RelationshipField) error
// Validate morph type is registered
ValidateMorphType(ctx context.Context, value interface{}, field RelationshipField) error
}
RelationshipValidator handles validation of relationships
type RelationshipValidatorImpl ¶
type RelationshipValidatorImpl struct {
}
RelationshipValidatorImpl, RelationshipValidator interface'ini implement eden struct'tır.
Bu struct, tüm ilişki tiplerinin doğrulanması için gerekli metodları sağlar. Veritabanı bağlantısı veya query builder bu struct'a eklenerek gerçek doğrulama işlemleri yapılabilir.
Özellikler ¶
- Foreign key doğrulama - Pivot tablo doğrulama - Polimorfik tip doğrulama - İlişkili kaynak varlık kontrolü
Not ¶
Şu anki implementasyon placeholder'dır. Gerçek kullanımda veritabanı bağlantısı eklenmeli ve doğrulama sorguları çalıştırılmalıdır.
func NewRelationshipValidator ¶
func NewRelationshipValidator() *RelationshipValidatorImpl
NewRelationshipValidator, yeni bir ilişki validator'ı oluşturur.
Bu constructor, RelationshipValidatorImpl struct'ının yeni bir instance'ını döndürür. Döndürülen validator, tüm ilişki tiplerinin doğrulanması için kullanılabilir.
Döndürür ¶
- Yapılandırılmış RelationshipValidatorImpl pointer'ı
Örnek ¶
```go validator := fields.NewRelationshipValidator()
// Validator'ı kullanarak ilişkileri doğrula err := validator.ValidateBelongsTo(ctx, userID, belongsToField)
if err != nil {
// Hata yönetimi
}
```
Not ¶
Şu anki implementasyon placeholder'dır. Gerçek kullanımda veritabanı bağlantısı constructor'a parametre olarak geçilebilir.
func (*RelationshipValidatorImpl) ValidateBelongsTo ¶
func (rv *RelationshipValidatorImpl) ValidateBelongsTo(ctx context.Context, value interface{}, field *BelongsToField) error
ValidateBelongsTo, BelongsTo ilişkilerini doğrular.
Bu metod, bir kaydın başka bir kayda ait olduğu (BelongsTo) ilişkilerin geçerliliğini kontrol eder. Alan zorunlu ise ve değer nil ise hata döndürür. Gerçek implementasyonda veritabanı sorgusu yaparak ilişkili kaynağın varlığı kontrol edilmelidir.
Parametreler ¶
- `ctx`: Context - İşlem context'i - `value`: interface{} - Doğrulanacak ilişki değeri (parent kaynak ID'si) - `field`: *BelongsToField - BelongsTo alan tanımı
Döndürür ¶
- `error`: Doğrulama hatası (varsa), nil (başarılı ise)
Hatalar ¶
- `RelationshipError`: Alan zorunlu ve değer nil ise
Örnek ¶
```go validator := fields.NewRelationshipValidator()
// Post -> User ilişkisini doğrula belongsToField := fields.NewBelongsTo("user", "users").Required() err := validator.ValidateBelongsTo(ctx, userID, belongsToField)
if err != nil {
// İlişkili kullanıcı bulunamadı veya zorunlu alan boş
log.Printf("BelongsTo doğrulama hatası: %v", err)
}
```
İşlem Adımları (Gerçek İmplementasyon) ¶
1. Değerin nil olup olmadığını kontrol et 2. Alan zorunlu ise ve değer nil ise hata döndür 3. Veritabanında ilişkili kaynağı sorgula 4. Kaynak bulunamazsa hata döndür
Not ¶
BelongsTo ilişkileri genellikle foreign key ile tanımlanır. Örneğin, bir Post kaydı user_id foreign key'i ile User kaydına bağlanır.
func (*RelationshipValidatorImpl) ValidateBelongsToMany ¶
func (rv *RelationshipValidatorImpl) ValidateBelongsToMany(ctx context.Context, value interface{}, field *BelongsToManyField) error
ValidateBelongsToMany, BelongsToMany ilişkilerini doğrular.
Bu metod, çoka-çok (many-to-many) ilişkilerin geçerliliğini kontrol eder. BelongsToMany ilişkileri pivot tablo kullanarak iki kaydı birbirine bağlar. Gerçek implementasyonda pivot tablosundaki tüm girişlerin var olduğu ve hem foreign key'lerin hem de related key'lerin geçerli olduğu kontrol edilmelidir.
Parametreler ¶
- `ctx`: Context - İşlem context'i - `value`: interface{} - Doğrulanacak ilişki değerleri (pivot tablo girişleri) - `field`: *BelongsToManyField - BelongsToMany alan tanımı
Döndürür ¶
- `error`: Doğrulama hatası (varsa), nil (başarılı ise)
Örnek ¶
```go validator := fields.NewRelationshipValidator()
// User -> Roles ilişkisini doğrula (pivot: role_user) belongsToManyField := fields.NewBelongsToMany("roles", "roles").
PivotTable("role_user").
ForeignKey("user_id").
RelatedKey("role_id")
err := validator.ValidateBelongsToMany(ctx, roleIDs, belongsToManyField)
if err != nil {
// Pivot tablo girişleri veya ilişkili kayıtlar geçersiz
log.Printf("BelongsToMany doğrulama hatası: %v", err)
}
```
İşlem Adımları (Gerçek İmplementasyon) ¶
1. Pivot tablo girişlerini çıkar 2. Tüm girişlerin pivot tablosunda var olduğunu doğrula 3. Foreign key'lerin ve related key'lerin geçerli olduğunu doğrula
Not ¶
BelongsToMany ilişkileri üç tablo kullanır: iki ana tablo ve bir pivot tablo. Örneğin, User ve Role tabloları arasında role_user pivot tablosu ile çoka-çok ilişki kurulabilir.
func (*RelationshipValidatorImpl) ValidateExists ¶
func (rv *RelationshipValidatorImpl) ValidateExists(ctx context.Context, value interface{}, field RelationshipField) error
ValidateExists, ilişkili kaynağın var olup olmadığını doğrular.
Bu metod, verilen değerin nil olup olmadığını kontrol eder ve alan zorunlu ise hata döndürür. Gerçek implementasyonda veritabanı sorgusu yaparak ilişkili kaynağın varlığı kontrol edilmelidir.
Parametreler ¶
- `ctx`: Context - İşlem context'i - `value`: interface{} - Doğrulanacak değer (ilişkili kaynak ID'si) - `field`: RelationshipField - İlişki alan tanımı
Döndürür ¶
- `error`: Doğrulama hatası (varsa), nil (başarılı ise)
Hatalar ¶
- `RelationshipError`: Alan zorunlu ve değer nil ise
Örnek ¶
```go validator := fields.NewRelationshipValidator() err := validator.ValidateExists(ctx, userID, belongsToField)
if err != nil {
// İlişkili kaynak bulunamadı veya zorunlu alan boş
log.Printf("Doğrulama hatası: %v", err)
}
```
Not ¶
Şu anki implementasyon sadece nil kontrolü yapar. Gerçek kullanımda veritabanı sorgusu eklenmeli ve kaynağın varlığı kontrol edilmelidir.
func (*RelationshipValidatorImpl) ValidateForeignKey ¶
func (rv *RelationshipValidatorImpl) ValidateForeignKey(ctx context.Context, value interface{}, field RelationshipField) error
ValidateForeignKey, foreign key referanslarını doğrular.
Bu metod, verilen değerin geçerli bir foreign key olup olmadığını kontrol eder. Gerçek implementasyonda veritabanı sorgusu yaparak foreign key'in ilişkili tabloda var olup olmadığı kontrol edilmelidir.
Parametreler ¶
- `ctx`: Context - İşlem context'i - `value`: interface{} - Doğrulanacak foreign key değeri - `field`: RelationshipField - İlişki alan tanımı
Döndürür ¶
- `error`: Doğrulama hatası (varsa), nil (başarılı ise)
Örnek ¶
```go validator := fields.NewRelationshipValidator() err := validator.ValidateForeignKey(ctx, categoryID, belongsToField)
if err != nil {
// Foreign key geçersiz
log.Printf("Foreign key hatası: %v", err)
}
```
İşlem Adımları (Gerçek İmplementasyon) ¶
1. Foreign key değerini çıkar 2. İlişkili kaynak tablosunu sorgula 3. Foreign key'in var olduğunu doğrula
Not ¶
Şu anki implementasyon sadece nil kontrolü yapar. Gerçek kullanımda veritabanı sorgusu eklenmeli ve foreign key'in varlığı kontrol edilmelidir.
func (*RelationshipValidatorImpl) ValidateHasMany ¶
func (rv *RelationshipValidatorImpl) ValidateHasMany(ctx context.Context, value interface{}, field *HasManyField) error
ValidateHasMany, HasMany ilişkilerini doğrular.
Bu metod, bir kaydın birden fazla ilişkili kayda sahip olduğu (HasMany) ilişkilerin geçerliliğini kontrol eder. Gerçek implementasyonda veritabanı sorgusu yaparak tüm foreign key'lerin geçerli olduğu kontrol edilmelidir.
Parametreler ¶
- `ctx`: Context - İşlem context'i - `value`: interface{} - Doğrulanacak ilişki değerleri (child kaynak ID'leri) - `field`: *HasManyField - HasMany alan tanımı
Döndürür ¶
- `error`: Doğrulama hatası (varsa), nil (başarılı ise)
Örnek ¶
```go validator := fields.NewRelationshipValidator()
// User -> Posts ilişkisini doğrula hasManyField := fields.NewHasMany("posts", "posts") err := validator.ValidateHasMany(ctx, postIDs, hasManyField)
if err != nil {
// İlişkili kayıtlar geçersiz
log.Printf("HasMany doğrulama hatası: %v", err)
}
```
İşlem Adımları (Gerçek İmplementasyon) ¶
1. Foreign key değerlerini çıkar 2. İlişkili kaynak tablosunu sorgula 3. Tüm foreign key'lerin geçerli olduğunu doğrula
Not ¶
HasMany ilişkileri genellikle child tabloda foreign key ile tanımlanır. Örneğin, bir User kaydı birden fazla Post kaydına sahip olabilir ve her Post kaydı user_id foreign key'i ile User'a bağlanır.
func (*RelationshipValidatorImpl) ValidateHasOne ¶
func (rv *RelationshipValidatorImpl) ValidateHasOne(ctx context.Context, value interface{}, field *HasOneField) error
ValidateHasOne, HasOne ilişkilerini doğrular.
Bu metod, bir kaydın tek bir ilişkili kayda sahip olduğu (HasOne) ilişkilerin geçerliliğini kontrol eder. Gerçek implementasyonda veritabanı sorgusu yaparak en fazla bir ilişkili kaynağın var olduğu kontrol edilmelidir.
Parametreler ¶
- `ctx`: Context - İşlem context'i - `value`: interface{} - Doğrulanacak ilişki değeri (child kaynak ID'si) - `field`: *HasOneField - HasOne alan tanımı
Döndürür ¶
- `error`: Doğrulama hatası (varsa), nil (başarılı ise)
Örnek ¶
```go validator := fields.NewRelationshipValidator()
// User -> Profile ilişkisini doğrula hasOneField := fields.NewHasOne("profile", "profiles") err := validator.ValidateHasOne(ctx, profileID, hasOneField)
if err != nil {
// İlişkili kayıt geçersiz veya birden fazla kayıt var
log.Printf("HasOne doğrulama hatası: %v", err)
}
```
İşlem Adımları (Gerçek İmplementasyon) ¶
1. Foreign key değerini çıkar 2. İlişkili kaynak tablosunu sorgula 3. En fazla bir ilişkili kaynağın var olduğunu doğrula
Not ¶
HasOne ilişkileri HasMany'ye benzer ancak tek bir kayıt ile sınırlıdır. Örneğin, bir User kaydı tek bir Profile kaydına sahip olabilir ve Profile kaydı user_id foreign key'i ile User'a bağlanır.
func (*RelationshipValidatorImpl) ValidateMorphTo ¶
func (rv *RelationshipValidatorImpl) ValidateMorphTo(ctx context.Context, value interface{}, field *MorphTo) error
ValidateMorphTo, MorphTo ilişkilerini doğrular.
Bu metod, polimorfik (MorphTo) ilişkilerin geçerliliğini kontrol eder. MorphTo ilişkileri, bir kaydın birden fazla farklı model tipine bağlanabilmesini sağlar. Gerçek implementasyonda morph tipinin kayıtlı olduğu, ilgili kaynak tablosunun sorgulandığı ve kaynağın var olduğu kontrol edilmelidir.
Parametreler ¶
- `ctx`: Context - İşlem context'i - `value`: interface{} - Doğrulanacak morph değeri (tip ve ID içerir) - `field`: *MorphTo - MorphTo alan tanımı
Döndürür ¶
- `error`: Doğrulama hatası (varsa), nil (başarılı ise)
Hatalar ¶
- `RelationshipError`: Hiç morph tipi kayıtlı değilse
Örnek ¶
```go validator := fields.NewRelationshipValidator()
// Comment -> Commentable (Post veya Video) ilişkisini doğrula morphToField := fields.NewMorphTo("commentable").
AddType("post", "posts").
AddType("video", "videos")
// Morph değeri: {type: "post", id: 123}
morphValue := map[string]interface{}{
"commentable_type": "post",
"commentable_id": 123,
}
err := validator.ValidateMorphTo(ctx, morphValue, morphToField)
if err != nil {
// Morph tipi kayıtlı değil veya ilişkili kaynak bulunamadı
log.Printf("MorphTo doğrulama hatası: %v", err)
}
```
İşlem Adımları (Gerçek İmplementasyon) ¶
1. Değerden morph tipini çıkar 2. Tipin alan tanımındaki tip eşleştirmelerinde kayıtlı olup olmadığını kontrol et 3. İlgili kaynak tablosunu sorgula 4. Kaynağın var olduğunu doğrula
Not ¶
MorphTo ilişkileri için en az bir tip kaydı zorunludur. Tip eşleştirmeleri morph_type sütunundaki değerleri gerçek model isimlerine çevirir. Örneğin: "post" -> "posts" tablosu, "video" -> "videos" tablosu
Referans ¶
Detaylı polimorfik ilişki dokümantasyonu için: `docs/Relationships.md`
func (*RelationshipValidatorImpl) ValidateMorphType ¶
func (rv *RelationshipValidatorImpl) ValidateMorphType(ctx context.Context, value interface{}, field RelationshipField) error
ValidateMorphType, morph tipinin kayıtlı olup olmadığını doğrular.
Bu metod, polimorfik ilişkilerde (MorphTo) kullanılan morph tipinin alan tanımında kayıtlı olup olmadığını kontrol eder. MorphTo ilişkileri birden fazla model tipine bağlanabildiği için, tip eşleştirmelerinin doğru yapılandırılması kritiktir.
Parametreler ¶
- `ctx`: Context - İşlem context'i - `value`: interface{} - Doğrulanacak morph değeri - `field`: RelationshipField - İlişki alan tanımı
Döndürür ¶
- `error`: Doğrulama hatası (varsa), nil (başarılı ise)
Hatalar ¶
- `RelationshipError`: MorphTo alanında hiç tip kayıtlı değilse
Örnek ¶
```go validator := fields.NewRelationshipValidator() err := validator.ValidateMorphType(ctx, morphValue, morphToField)
if err != nil {
// Morph tipi kayıtlı değil
log.Printf("Morph tip hatası: %v", err)
}
```
İşlem Adımları (Gerçek İmplementasyon) ¶
1. Değerden morph tipini çıkar 2. Tipin alan tanımındaki tip eşleştirmelerinde kayıtlı olup olmadığını kontrol et 3. Kayıtlı değilse hata döndür
Not ¶
MorphTo alanları için en az bir tip kaydı zorunludur. Aksi takdirde polimorfik ilişki kurulamaz.
func (*RelationshipValidatorImpl) ValidatePivot ¶
func (rv *RelationshipValidatorImpl) ValidatePivot(ctx context.Context, value interface{}, field RelationshipField) error
ValidatePivot, pivot tablo girişlerini doğrular.
Bu metod, çoka-çok (many-to-many) ilişkilerde kullanılan pivot tablo girişlerinin geçerliliğini kontrol eder. Gerçek implementasyonda pivot tablosundaki tüm girişlerin var olduğu ve foreign key'lerin geçerli olduğu doğrulanmalıdır.
Parametreler ¶
- `ctx`: Context - İşlem context'i - `value`: interface{} - Doğrulanacak pivot tablo değerleri - `field`: RelationshipField - İlişki alan tanımı
Döndürür ¶
- `error`: Doğrulama hatası (varsa), nil (başarılı ise)
Örnek ¶
```go validator := fields.NewRelationshipValidator() err := validator.ValidatePivot(ctx, pivotData, belongsToManyField)
if err != nil {
// Pivot tablo girişleri geçersiz
log.Printf("Pivot doğrulama hatası: %v", err)
}
```
İşlem Adımları (Gerçek İmplementasyon) ¶
1. Pivot tablo girişlerini çıkar 2. Tüm girişlerin pivot tablosunda var olduğunu doğrula 3. Foreign key'lerin geçerli olduğunu doğrula
Not ¶
Şu anki implementasyon sadece nil kontrolü yapar. Gerçek kullanımda pivot tablo sorguları eklenmeli ve girişlerin varlığı kontrol edilmelidir.
type Resolver ¶
Resolver, alan değerlerini çözümleyen interface'dir.
Bu tip, core.Resolver'ın bir alias'ıdır ve özel alan değeri çözümleme mantığı sağlamak için kullanılır.
Daha fazla bilgi için pkg/core/resolver.go dosyasına bakın.
type Schema ¶
type Schema struct {
Name string `json:"name"` // Görünen Ad
Key string `json:"key"` // Veri Anahtarı
View string `json:"view"` // Frontend Bileşeni
Data interface{} `json:"data"` // Alan Değeri
Type ElementType `json:"type"` // Veri Tipi
Context ElementContext `json:"context"` // Görünüm Bağlamı (List, Detail, Form)
IsReadOnly bool `json:"read_only"` // Salt okunur mu?
IsDisabled bool `json:"disabled"` // Devre dışı mı?
IsImmutable bool `json:"immutable"` // Değiştirilemez mi?
Props map[string]interface{} `json:"props"` // Ekstra özellikler
IsRequired bool `json:"required"` // Zorunlu mu?
IsNullable bool `json:"nullable"` // Boş bırakılabilir mi?
PlaceholderText string `json:"placeholder"`
LabelText string `json:"label"`
HelpTextContent string `json:"help_text"`
IsFilterable bool `json:"filterable"`
IsSortable bool `json:"sortable"`
GlobalSearch bool `json:"searchable"`
IsStacked bool `json:"stacked"`
TextAlign string `json:"text_align"`
Suggestions []interface{} `json:"suggestions"`
ExtractCallback func(value interface{}, item interface{}, c *fiber.Ctx) interface{} `json:"-"`
VisibilityCallback VisibilityFunc `json:"-"`
StorageCallback StorageCallbackFunc `json:"-"`
ModifyCallback func(value interface{}, c *fiber.Ctx) interface{} `json:"-"`
AutoOptionsConfig core.AutoOptionsConfig `json:"-"`
// Validation (Kategori 1)
ValidationRules []ValidationRule `json:"validation_rules"`
CreationValidationRules []ValidationRule `json:"creation_validation_rules,omitempty"`
UpdateValidationRules []ValidationRule `json:"update_validation_rules,omitempty"`
CustomValidators []ValidatorFunc `json:"-"`
// Display (Kategori 2)
DisplayCallback func(value interface{}, item interface{}) interface{} `json:"-"`
DisplayedAs string `json:"displayed_as"`
DisplayUsingLabelsFlag bool `json:"display_using_labels"`
ResolveHandleValue string `json:"resolve_handle"`
// Dependencies (Kategori 3)
DependsOnFields []string `json:"depends_on"`
DependencyRules map[string]interface{} `json:"dependency_rules"`
DependencyCallback DependencyCallbackFunc `json:"-"`
DependencyCallbackOnCreate DependencyCallbackFunc `json:"-"`
DependencyCallbackOnUpdate DependencyCallbackFunc `json:"-"`
// Suggestions (Kategori 4)
SuggestionsCallback func(string) []interface{} `json:"-"`
AutoCompleteURL string `json:"autocomplete_url"`
MinCharsForSuggestionsVal int `json:"min_chars_for_suggestions"`
// Attachments (Kategori 5)
AcceptedMimeTypes []string `json:"accepted_mime_types"`
MaxFileSize int64 `json:"max_file_size"`
StorageDisk string `json:"storage_disk"`
StoragePath string `json:"storage_path"`
UploadCallback func(interface{}, interface{}) error `json:"-"`
RemoveEXIFDataFlag bool `json:"remove_exif_data"`
// Repeater (Kategori 6)
RepeaterFields []core.Element `json:"-"`
MinRepeatsCount int `json:"min_repeats"`
MaxRepeatsCount int `json:"max_repeats"`
// Rich Text (Kategori 7)
EditorType string `json:"editor_type"`
EditorLanguage string `json:"editor_language"`
EditorTheme string `json:"editor_theme"`
// Status (Kategori 8)
StatusColors map[string]string `json:"status_colors"`
BadgeVariant string `json:"badge_variant"`
// Pivot (Kategori 9)
IsPivotField bool `json:"is_pivot_field"`
PivotResourceName string `json:"pivot_resource_name"`
// GORM Veritabanı Yapılandırması (Kategori 10)
GormConfiguration *GormConfig `json:"-"`
// Context for i18n (Kategori 11)
FiberCtx *fiber.Ctx `json:"-"`
}
Schema, bir alanın temel yapılandırmasını ve durumunu tutan yapıdır.
Schema, Go Panel API'nin alan sisteminin temel yapı taşıdır. Her alan, bir Schema örneği olarak temsil edilir ve frontend ile backend arasında veri taşımak için kullanılır.
Temel Özellikler ¶
- **JSON Serileştirme**: Tüm alanlar JSON formatında serileştirilebilir - **Veri Çıkarma**: Reflection kullanarak model'lerden veri çıkarır - **Görünürlük Kontrolü**: Farklı bağlamlarda (list, detail, form) görünürlük kontrolü - **Callback Desteği**: Extract, Modify, Resolve, Storage callback'leri - **Fluent API**: Zincirleme metod çağrıları ile kolay yapılandırma
Kategoriler ¶
Schema, 10 ana kategoride özellik içerir:
1. **Temel Özellikler**: Name, Key, View, Data, Type, Context 2. **Durum Özellikleri**: IsReadOnly, IsDisabled, IsImmutable, IsRequired, IsNullable 3. **UI Özellikleri**: PlaceholderText, LabelText, HelpTextContent, IsStacked, TextAlign 4. **Arama/Filtreleme**: IsFilterable, IsSortable, GlobalSearch 5. **Callback'ler**: ExtractCallback, VisibilityCallback, StorageCallback, ModifyCallback 6. **Doğrulama**: ValidationRules, CustomValidators 7. **Görüntüleme**: DisplayCallback, DisplayedAs, DisplayUsingLabelsFlag 8. **Bağımlılıklar**: DependsOnFields, DependencyRules 9. **Öneriler**: SuggestionsCallback, AutoCompleteURL, MinCharsForSuggestionsVal 10. **Dosya Yükleme**: AcceptedMimeTypes, MaxFileSize, StorageDisk, StoragePath
Kullanım Örneği ¶
schema := &fields.Schema{
Key: "email",
Name: "E-posta",
View: "email-field",
Type: core.TYPE_EMAIL,
Props: make(map[string]interface{}),
}
schema.OnList().OnDetail().OnForm().Required().Searchable()
Mixin Desteği ¶
Schema, mixin pattern'ini desteklemez (çünkü kendisi bir veri yapısıdır), ancak mixin özelliklerini (Searchable, Sortable, vb.) field'lar aracılığıyla kullanabilir.
Daha fazla bilgi için docs/Fields.md ve .docs/ARCHITECTURE.md dosyalarına bakın.
func Audio ¶
Bu fonksiyon, ses dosyası yükleme alanı oluşturur ve yapılandırır.
Kullanım Senaryosu: - Podcast bölümleri, müzik dosyaları, ses notları gibi ses dosyaları yüklemek için - Genellikle MP3, WAV, OGG, M4A gibi ses formatlarını destekler - Ses oynatıcı entegrasyonu yapılabilir
Parametreler:
- name: Alanın görüntü adı (örn: "Ses Dosyası", "Podcast")
- attribute: İsteğe bağlı veritabanı sütun adı
Dönüş Değeri:
- *Schema: Yapılandırılmış ses alan şeması pointer'ı
Örnek Kullanım:
audioField := Audio("Ses Dosyası")
podcastField := Audio("Podcast Bölümü", "podcast_episode")
Önemli Notlar:
- Frontend bileşeni "file-field" olarak ayarlanır
- TYPE_AUDIO sabiti ile alan türü belirtilir
- Ses codec ve format doğrulaması yapılabilir
- Ses süresi metadata'sı çıkarılabilir
func Badge ¶
Bu fonksiyon, badge/status gösterim alanı oluşturur ve yapılandırır.
Kullanım Senaryosu: - Durum göstermek için (örn: "Aktif", "Beklemede", "Tamamlandı") - Renk kodlu etiketler ile görsel durum gösterimi - Genellikle salt okunur (read-only) alan olarak kullanılır
Parametreler:
- name: Alanın görüntü adı (örn: "Durum", "Etiket")
- attribute: İsteğe bağlı veritabanı sütun adı
Dönüş Değeri:
- *Schema: Yapılandırılmış badge alan şeması pointer'ı
Örnek Kullanım:
statusBadge := Badge("Durum")
tagBadge := Badge("Etiket", "tag")
Önemli Notlar:
- Frontend bileşeni "badge-field" olarak ayarlanır
- TYPE_BADGE sabiti ile alan türü belirtilir
- Renk ve stil Props haritasına eklenebilir
- Genellikle liste görünümünde gösterilir
func BooleanGroup ¶
Bu fonksiyon, birden fazla boolean seçeneği checkbox group olarak gösterir ve yapılandırır.
Kullanım Senaryosu: - Birden fazla özelliği aynı anda seçmek için (örn: İzinler, Tercihler) - Her seçenek bağımsız olarak seçilebilir veya seçimi kaldırılabilir - Genellikle JSON array veya virgülle ayrılmış string olarak saklanır
Parametreler:
- name: Alanın görüntü adı (örn: "İzinler", "Tercihler")
- attribute: İsteğe bağlı veritabanı sütun adı
Dönüş Değeri:
- *Schema: Yapılandırılmış boolean grup alan şeması pointer'ı
Örnek Kullanım:
permissionsGroup := BooleanGroup("İzinler")
preferencesGroup := BooleanGroup("Tercihler", "user_preferences")
Önemli Notlar:
- Frontend bileşeni "boolean-group-field" olarak ayarlanır
- TYPE_BOOLEAN_GROUP sabiti ile alan türü belirtilir
- Seçenekler Props haritasına "options" anahtarı ile eklenebilir
- Genellikle JSON array olarak veritabanında saklanır
func Code ¶
Bu fonksiyon, kod editörü alanı oluşturur ve yapılandırır.
Kullanım Senaryosu: - JSON, JavaScript, SQL, HTML gibi kod yazma ve düzenleme için - Syntax highlighting ve kod biçimlendirmesi destekler - Genellikle Monaco Editor veya benzer editörler ile entegre edilir
Parametreler:
- name: Alanın görüntü adı (örn: "Kod", "SQL Sorgusu")
- attribute: İsteğe bağlı veritabanı sütun adı
Dönüş Değeri:
- *Schema: Yapılandırılmış kod alan şeması pointer'ı
Örnek Kullanım:
codeField := Code("Kod")
sqlField := Code("SQL Sorgusu", "sql_query")
Önemli Notlar:
- Frontend bileşeni "code-field" olarak ayarlanır
- TYPE_CODE sabiti ile alan türü belirtilir
- Dil (language) Props haritasına eklenebilir (json, javascript, sql, html vb.)
- Tema (theme) ayarlanabilir (light, dark vb.)
func Collection ¶
Bu fonksiyon, ilişkili kayıtların listesini gösteren (HasMany ilişkisi) alan oluşturur ve yapılandırır.
Kullanım Senaryosu: - Bir kaynağın birden fazla ilişkili kaynağa sahip olduğu bire-çok ilişkiyi temsil eder - Örn: Bir yazının birden fazla yorumu, bir kategorinin birden fazla ürünü - Genellikle listede gizlenir, detay sayfasında ilişkili kayıtların tablosu gösterilir
Parametreler:
- name: Alanın görüntü adı (örn: "Yorumlar", "Ürünler")
- resource: İlişkili kaynağın adı (örn: "comments", "products")
- attribute: İsteğe bağlı veritabanı sütun adı
Dönüş Değeri:
- *Schema: Yapılandırılmış koleksiyon alan şeması pointer'ı
Örnek Kullanım:
commentsCollection := Collection("Yorumlar", "comments")
productsCollection := Collection("Ürünler", "products", "product_ids")
Önemli Notlar:
- Frontend bileşeni "collection-field" olarak ayarlanır
- TYPE_COLLECTION sabiti ile alan türü belirtilir
- Context HIDE_ON_LIST ile liste görünümünde gizlenir
- Detay sayfasında ilişkili kayıtların listesi gösterilir
func Color ¶
Bu fonksiyon, renk seçici alanı oluşturur ve yapılandırır.
Kullanım Senaryosu: - Tema rengi, arka plan rengi, vurgu rengi gibi renk seçimi için - Hex, RGB, HSL format desteği sağlar - Renk paleti veya özel renk seçici ile seçim yapılabilir
Parametreler:
- name: Alanın görüntü adı (örn: "Renk", "Tema Rengi")
- attribute: İsteğe bağlı veritabanı sütun adı
Dönüş Değeri:
- *Schema: Yapılandırılmış renk alan şeması pointer'ı
Örnek Kullanım:
colorField := Color("Renk")
themeColorField := Color("Tema Rengi", "theme_color")
Önemli Notlar:
- Frontend bileşeni "color-field" olarak ayarlanır
- TYPE_COLOR sabiti ile alan türü belirtilir
- Hex formatı (#RRGGBB) standart olarak kullanılır
- Alfa (opacity) değeri eklenebilir
func Combobox ¶
Bu fonksiyon, çoktan seçmeli veya arama yapılabilir seçim alanı oluşturur ve yapılandırır.
Kullanım Senaryosu: - Uzun seçenekler listesinden arama yaparak seçim yapmak için - Otomatik tamamlama (autocomplete) özelliği ile hızlı seçim - Genellikle API'den dinamik olarak yüklenen seçenekler için
Parametreler:
- name: Alanın görüntü adı (örn: "Ürün", "Müşteri")
- attribute: İsteğe bağlı veritabanı sütun adı
Dönüş Değeri:
- *Schema: Yapılandırılmış combobox alan şeması pointer'ı
Örnek Kullanım:
productCombo := Combobox("Ürün")
customerCombo := Combobox("Müşteri", "customer_id")
Önemli Notlar:
- Frontend bileşeni "combobox-field" olarak ayarlanır
- TYPE_SELECT sabiti ile alan türü belirtilir (veya TYPE_COMBOBOX eğer yeni tip gerekiyorsa)
- Arama ve filtreleme işlevselliği sağlar
- Genellikle Select'ten daha gelişmiş bir bileşendir
func Connect ¶
Bu fonksiyon, çoktan çoka (BelongsToMany ilişkisi) ilişki kurmak için kullanılır ve yapılandırır.
Kullanım Senaryosu: - İki kaynak arasında çoktan çoka ilişkiyi temsil eder - Örn: Bir ürünün birden fazla etiketi, bir yazının birden fazla kategorisi - Genellikle ara tablo (pivot table) ile yönetilir - Listede gizlenir, detay sayfasında ilişkili kayıtları seçmek için kullanılır
Parametreler:
- name: Alanın görüntü adı (örn: "Etiketler", "Kategoriler")
- resource: İlişkili kaynağın adı (örn: "tags", "categories")
- attribute: İsteğe bağlı veritabanı sütun adı
Dönüş Değeri:
- *Schema: Yapılandırılmış bağlantı alan şeması pointer'ı
Örnek Kullanım:
tagsConnect := Connect("Etiketler", "tags")
categoriesConnect := Connect("Kategoriler", "categories", "category_ids")
Önemli Notlar:
- Frontend bileşeni "connect-field" olarak ayarlanır
- TYPE_CONNECT sabiti ile alan türü belirtilir
- Context HIDE_ON_LIST ile liste görünümünde gizlenir
- Detay sayfasında çoklu seçim yapılabilir
func Date ¶
Bu fonksiyon, tarih seçim alanı (datepicker) oluşturur ve yapılandırır.
Kullanım Senaryosu: - Doğum tarihi, etkinlik tarihi, başlangıç tarihi gibi tarih girişi için - Takvim arayüzü ile tarih seçimi yapılabilir - Tarih formatı ve aralığı kısıtlaması eklenebilir
Parametreler:
- name: Alanın görüntü adı (örn: "Doğum Tarihi", "Etkinlik Tarihi")
- attribute: İsteğe bağlı veritabanı sütun adı
Dönüş Değeri:
- *Schema: Yapılandırılmış tarih alan şeması pointer'ı
Örnek Kullanım:
dateField := Date("Doğum Tarihi")
eventField := Date("Etkinlik Tarihi", "event_date")
Önemli Notlar:
- Frontend bileşeni "date-field" olarak ayarlanır
- TYPE_DATE sabiti ile alan türü belirtilir
- Tarih formatı (YYYY-MM-DD) standart olarak kullanılır
- Min/Max tarih kısıtlaması eklenebilir
func DateTime ¶
Bu fonksiyon, tarih ve saat seçim alanı oluşturur ve yapılandırır.
Kullanım Senaryosu: - Etkinlik başlangıç zamanı, randevu saati, yayın zamanı gibi tarih ve saat girişi için - Takvim ve saat seçici arayüzü ile tarih ve saat seçimi yapılabilir - Zaman dilimi (timezone) desteği eklenebilir
Parametreler:
- name: Alanın görüntü adı (örn: "Randevu Saati", "Yayın Zamanı")
- attribute: İsteğe bağlı veritabanı sütun adı
Dönüş Değeri:
- *Schema: Yapılandırılmış tarih-saat alan şeması pointer'ı
Örnek Kullanım:
datetimeField := DateTime("Randevu Saati")
eventField := DateTime("Etkinlik Zamanı", "event_datetime")
Önemli Notlar:
- Frontend bileşeni "datetime-field" olarak ayarlanır
- TYPE_DATETIME sabiti ile alan türü belirtilir
- ISO 8601 formatı (YYYY-MM-DDTHH:mm:ss) standart olarak kullanılır
- Zaman dilimi bilgisi saklanabilir
func Detail ¶
Bu fonksiyon, bir kaynağın detayını gösteren (HasOne ilişkisi) alan oluşturur ve yapılandırır.
Kullanım Senaryosu: - Bir kaynağın başka bir kaynağa sahip olduğu bire-bir ilişkiyi temsil eder - Örn: Bir kullanıcının bir profili, bir ürünün bir açıklaması - Genellikle listede gizlenir, detay sayfasında gösterilir
Parametreler:
- name: Alanın görüntü adı (örn: "Profil", "Açıklama")
- resource: İlişkili kaynağın adı (örn: "profiles", "descriptions")
- attribute: İsteğe bağlı veritabanı sütun adı
Dönüş Değeri:
- *Schema: Yapılandırılmış detay alan şeması pointer'ı
Örnek Kullanım:
profileDetail := Detail("Profil", "profiles")
descDetail := Detail("Açıklama", "descriptions", "description_id")
Önemli Notlar:
- Frontend bileşeni "detail-field" olarak ayarlanır
- TYPE_DETAIL sabiti ile alan türü belirtilir
- Context HIDE_ON_LIST ile liste görünümünde gizlenir
- Detay sayfasında ilişkili kaynağın bilgileri gösterilir
func Email ¶
Bu fonksiyon, e-posta giriş alanı (input type="email") oluşturur ve yapılandırır.
Kullanım Senaryosu: - Kullanıcı e-posta adresi, iletişim e-postası gibi e-posta girişi için - Otomatik olarak e-posta formatı doğrulaması yapılır - Tarayıcı tarafından native e-posta doğrulaması desteklenir
Parametreler:
- name: Alanın görüntü adı (örn: "E-posta", "İletişim E-postası")
- attribute: İsteğe bağlı veritabanı sütun adı
Dönüş Değeri:
- *Schema: Yapılandırılmış e-posta alan şeması pointer'ı
Örnek Kullanım:
emailField := Email("E-posta")
contactField := Email("İletişim E-postası", "contact_email")
Önemli Notlar:
- Frontend bileşeni "email-field" olarak ayarlanır
- TYPE_EMAIL sabiti ile alan türü belirtilir
- Backend'de regex veya email validator kütüphanesi ile doğrulama yapılmalı
- Benzersizlik kısıtlaması (unique constraint) eklenebilir
func File ¶
Bu fonksiyon, genel dosya yükleme alanı oluşturur ve yapılandırır.
Kullanım Senaryosu: - PDF, Word, Excel, ZIP gibi çeşitli dosya türlerini yüklemek için - Belge yönetimi, raporlar, ek dosyalar gibi genel dosya depolaması için - Dosya türü ve boyutu kısıtlaması eklenebilir
Parametreler:
- name: Alanın görüntü adı (örn: "Dosya", "Ek Dosya")
- attribute: İsteğe bağlı veritabanı sütun adı
Dönüş Değeri:
- *Schema: Yapılandırılmış dosya alan şeması pointer'ı
Örnek Kullanım:
fileField := File("Dosya")
attachmentField := File("Ek Dosya", "attachment")
Önemli Notlar:
- Frontend bileşeni "file-field" olarak ayarlanır
- TYPE_FILE sabiti ile alan türü belirtilir
- Dosya türü whitelist'i eklenebilir (örn: .pdf, .doc, .xls)
- Maksimum dosya boyutu kısıtlaması yapılabilir
func ID ¶
Bu fonksiyon, benzersiz kimlik alanını oluşturur ve yapılandırır.
Kullanım Senaryosu: - Veritabanı kayıtlarının birincil anahtarını temsil eder - Genellikle otomatik olarak oluşturulan ve değiştirilemeyen bir alandır - Yalnızca liste görünümünde gösterilir, form düzenlemesinde gizlenir
Parametreler:
- name: İsteğe bağlı alan adı (varsayılan: "ID")
Dönüş Değeri:
- *Schema: Yapılandırılmış ID alan şeması pointer'ı
Örnek Kullanım:
idField := ID() // Varsayılan "ID" adı ile
idField := ID("Kayıt Numarası") // Özel ad ile
Önemli Notlar:
- Veritabanı anahtarı her zaman "id" olarak ayarlanır
- OnlyOnList() metodu çağrılarak sadece liste görünümünde gösterilir
- Frontend bileşeni "id-field" olarak ayarlanır
func Image ¶
Bu fonksiyon, görsel yükleme alanı oluşturur ve yapılandırır.
Kullanım Senaryosu: - Ürün resimleri, profil fotoğrafları, banner görselleri gibi görsel dosyaları yüklemek için - Genellikle JPG, PNG, WebP gibi görsel formatlarını destekler - Ön izleme (preview) ve crop işlemleri yapılabilir
Parametreler:
- name: Alanın görüntü adı (örn: "Ürün Resmi", "Profil Fotoğrafı")
- attribute: İsteğe bağlı veritabanı sütun adı
Dönüş Değeri:
- *Schema: Yapılandırılmış görsel alan şeması pointer'ı
Örnek Kullanım:
imageField := Image("Ürün Resmi")
avatarField := Image("Profil Fotoğrafı", "avatar")
Önemli Notlar:
- Frontend bileşeni "image-field" olarak ayarlanır
- TYPE_FILE sabiti ile alan türü belirtilir
- Dosya boyutu ve format kısıtlaması eklenebilir
- CDN veya cloud storage entegrasyonu yapılabilir
func KeyValue ¶
Bu fonksiyon, anahtar-değer ikilisi girişi sağlayan alan oluşturur ve yapılandırır.
Kullanım Senaryosu: - Dinamik ayarlar, meta veriler, özel özellikler gibi anahtar-değer çiftlerini depolamak için - JSON formatında saklanabilen esnek veri yapısı - Örn: {"color": "red", "size": "large", "material": "cotton"}
Parametreler:
- name: Alanın görüntü adı (örn: "Özellikler", "Meta Veriler")
- attribute: İsteğe bağlı veritabanı sütun adı
Dönüş Değeri:
- *Schema: Yapılandırılmış anahtar-değer alan şeması pointer'ı
Örnek Kullanım:
kvField := KeyValue("Özellikler")
metaField := KeyValue("Meta Veriler", "metadata")
Önemli Notlar:
- Frontend bileşeni "key-value-field" olarak ayarlanır
- TYPE_KEY_VALUE sabiti ile alan türü belirtilir
- Genellikle JSON formatında veritabanında saklanır
- Dinamik form alanları için idealdir
func Link ¶
Bu fonksiyon, başka bir kaynağa bağlantı (BelongsTo ilişkisi) oluşturur ve yapılandırır.
Kullanım Senaryosu: - Bir kaynağın başka bir kaynağa ait olduğu ilişkiyi temsil eder - Örn: Bir ürün bir kategoriye ait, bir yorum bir yazıya ait - Seçim alanı ile ilişkili kaynağı seçmek için kullanılır
Parametreler:
- name: Alanın görüntü adı (örn: "Kategori", "Yazar")
- resource: İlişkili kaynağın adı (örn: "categories", "authors")
- attribute: İsteğe bağlı veritabanı sütun adı
Dönüş Değeri:
- *Schema: Yapılandırılmış bağlantı alan şeması pointer'ı
Örnek Kullanım:
categoryLink := Link("Kategori", "categories")
authorLink := Link("Yazar", "authors", "author_id")
Önemli Notlar:
- Frontend bileşeni "link-field" olarak ayarlanır
- TYPE_LINK sabiti ile alan türü belirtilir
- Props haritasına "resource" anahtarı ile ilişkili kaynak adı eklenir
- Method chaining ile ek özellikler eklenebilir
func Matrix ¶
Matrix, satır/sütun bazlı JSON veri giriş alanı oluşturur.
Bu alan tipi; dinamik kolonlar, farklı hücre tipleri (text/select/checkbox/radio vb.) ve satır ekleme-silme davranışları gibi gelişmiş form ihtiyaçları için kullanılır.
Parametreler:
- name: Alanın görüntü adı
- attribute: İsteğe bağlı veritabanı sütun adı
Dönüş Değeri:
- *Schema: Yapılandırılmış matrix alan şeması pointer'ı
Örnek Kullanım:
matrix := Matrix("Variant Matrix", "variant_matrix")
Önemli Notlar:
- Frontend bileşeni "matrix-field" olarak ayarlanır
- TYPE_KEY_VALUE kullanılarak JSON tabanlı veri formatı korunur
func Money ¶
Money, para tutarı için özel bir alan oluşturur.
Varsayılan olarak: - view: "money-field" - type: TYPE_MONEY - currency: "USD" - currencies: DefaultCurrencies
func NewField ¶
Bu fonksiyon, yeni bir alan şeması oluşturur ve temel konfigürasyonunu başlatır.
Kullanım Senaryosu: - Tüm alan türlerinin temelini oluşturur - Alan adını ve veritabanı anahtarını ayarlar - Varsayılan özellikleri başlatır
Parametreler:
- name: Alanın görüntü adı (örn: "Kullanıcı Adı", "E-posta")
- attribute: İsteğe bağlı veritabanı sütun adı (varsayılan: name'i küçük harfe çevirip boşlukları alt çizgi ile değiştirir)
Dönüş Değeri:
- *Schema: Yapılandırılmış alan şeması pointer'ı
Örnek Kullanım:
field := NewField("Kullanıcı Adı") // Key: "kullanıcı_adı"
field := NewField("Kullanıcı Adı", "username") // Key: "username"
Önemli Notlar:
- Döndürülen Schema pointer'ı method chaining için kullanılabilir
- Props haritası boş olarak başlatılır, sonradan özellikler eklenebilir
- TextAlign varsayılan olarak "left" (sol hizalı) olarak ayarlanır
func Number ¶
Bu fonksiyon, sayı giriş alanı (input type="number") oluşturur ve yapılandırır.
Kullanım Senaryosu: - Yaş, fiyat, miktar, telefon numarası gibi sayısal değerlerin girişi için - Min/max değer kısıtlaması ve adım (step) ayarı yapılabilir - Otomatik olarak sayı dışı karakterleri filtreler
Parametreler:
- name: Alanın görüntü adı (örn: "Fiyat", "Miktar")
- attribute: İsteğe bağlı veritabanı sütun adı
Dönüş Değeri:
- *Schema: Yapılandırılmış sayı alan şeması pointer'ı
Örnek Kullanım:
priceField := Number("Fiyat")
quantityField := Number("Miktar", "quantity")
ageField := Number("Yaş", "age")
Önemli Notlar:
- Frontend bileşeni "number-field" olarak ayarlanır
- TYPE_NUMBER sabiti ile alan türü belirtilir
- Min/Max değerleri Props haritasına eklenebilir
- Step değeri (örn: 0.01 para birimi için) ayarlanabilir
func Password ¶
Bu fonksiyon, şifre giriş alanı (input type="password") oluşturur ve yapılandırır.
Kullanım Senaryosu: - Kullanıcı şifresi, API anahtarı, gizli token gibi hassas bilgilerin girişi için - Girilen karakterler maskelenir ve görüntülenmez - Genellikle şifre güç göstergesi ve göster/gizle butonu ile birlikte kullanılır
Parametreler:
- name: Alanın görüntü adı (örn: "Şifre", "Yeni Şifre")
- attribute: İsteğe bağlı veritabanı sütun adı
Dönüş Değeri:
- *Schema: Yapılandırılmış şifre alan şeması pointer'ı
Örnek Kullanım:
passField := Password("Şifre")
newPassField := Password("Yeni Şifre", "new_password")
Önemli Notlar:
- Frontend bileşeni "password-field" olarak ayarlanır
- TYPE_PASSWORD sabiti ile alan türü belirtilir
- Backend'de şifre hash'lenmeli (bcrypt, argon2 vb.)
- HTTPS üzerinden iletilmeli
func PolyCollection ¶
Bu fonksiyon, polimorfik koleksiyon (MorphMany ilişkisi) oluşturur ve yapılandırır.
Kullanım Senaryosu: - Bir kaynağın birden fazla farklı kaynak türüne ait olabileceği polimorfik bire-çok ilişkiyi temsil eder - Örn: Bir ürünün birden fazla açıklaması olabilir, bir yazının birden fazla yorumu olabilir - Genellikle listede gizlenir, detay sayfasında ilişkili kayıtların listesi gösterilir
Parametreler:
- name: Alanın görüntü adı (örn: "Açıklamalar", "Yorumlar")
- resource: İlişkili kaynağın adı (örn: "descriptions", "comments")
- attribute: İsteğe bağlı veritabanı sütun adı
Dönüş Değeri:
- *Schema: Yapılandırılmış polimorfik koleksiyon alan şeması pointer'ı
Örnek Kullanım:
polyCollection := PolyCollection("Açıklamalar", "descriptions")
commentsCollection := PolyCollection("Yorumlar", "comments", "comment_ids")
Önemli Notlar:
- Frontend bileşeni "poly-collection-field" olarak ayarlanır
- TYPE_POLY_COLLECTION sabiti ile alan türü belirtilir
- Context HIDE_ON_LIST ile liste görünümünde gizlenir
func PolyConnect ¶
Bu fonksiyon, polimorfik çoktan çoka (BelongsToMany ilişkisi) ilişki kurmak için kullanılır ve yapılandırır.
Kullanım Senaryosu: - Bir kaynağın birden fazla farklı kaynak türüne çoktan çoka ilişkiyi temsil eder - Örn: Bir ürünün birden fazla kategoriye ait olabilir, bir yazının birden fazla etiketi olabilir - Genellikle ara tablo (pivot table) ile yönetilir - Listede gizlenir, detay sayfasında ilişkili kayıtları seçmek için kullanılır
Parametreler:
- name: Alanın görüntü adı (örn: "Kategoriler", "Etiketler")
- resource: İlişkili kaynağın adı (örn: "categories", "tags")
- attribute: İsteğe bağlı veritabanı sütun adı
Dönüş Değeri:
- *Schema: Yapılandırılmış polimorfik bağlantı alan şeması pointer'ı
Örnek Kullanım:
polyConnect := PolyConnect("Kategoriler", "categories")
tagsConnect := PolyConnect("Etiketler", "tags", "tag_ids")
Önemli Notlar:
- Frontend bileşeni "poly-connect-field" olarak ayarlanır
- TYPE_POLY_CONNECT sabiti ile alan türü belirtilir
- Context HIDE_ON_LIST ile liste görünümünde gizlenir
- Detay sayfasında çoklu seçim yapılabilir
func PolyDetail ¶
Bu fonksiyon, polimorfik detay (MorphOne ilişkisi) oluşturur ve yapılandırır.
Kullanım Senaryosu: - Bir kaynağın birden fazla farklı kaynak türüne ait olabileceği polimorfik bire-bir ilişkiyi temsil eder - Örn: Bir ürünün bir açıklaması olabilir, bir yazının bir özeti olabilir - Genellikle listede gizlenir, detay sayfasında gösterilir
Parametreler:
- name: Alanın görüntü adı (örn: "Açıklama", "Özet")
- resource: İlişkili kaynağın adı (örn: "descriptions", "summaries")
- attribute: İsteğe bağlı veritabanı sütun adı
Dönüş Değeri:
- *Schema: Yapılandırılmış polimorfik detay alan şeması pointer'ı
Örnek Kullanım:
polyDetail := PolyDetail("Açıklama", "descriptions")
summaryDetail := PolyDetail("Özet", "summaries", "summary_id")
Önemli Notlar:
- Frontend bileşeni "poly-detail-field" olarak ayarlanır
- TYPE_POLY_DETAIL sabiti ile alan türü belirtilir
- Context HIDE_ON_LIST ile liste görünümünde gizlenir
func PolyLink ¶
Bu fonksiyon, polimorfik ilişki bağlantısı (MorphTo ilişkisi) oluşturur ve yapılandırır.
Kullanım Senaryosu: - Bir kaynağın birden fazla farklı kaynak türüne ait olabileceği polimorfik ilişkiyi temsil eder - Örn: Bir yorum bir yazıya veya bir ürüne ait olabilir - Genellikle "commentable_type" ve "commentable_id" sütunları ile yönetilir
Parametreler:
- name: Alanın görüntü adı (örn: "Bağlantılı Kaynak")
- attribute: İsteğe bağlı veritabanı sütun adı
Dönüş Değeri:
- *Schema: Yapılandırılmış polimorfik bağlantı alan şeması pointer'ı
Örnek Kullanım:
polyLink := PolyLink("Bağlantılı Kaynak")
commentableLink := PolyLink("Yorum Yapılan", "commentable")
Önemli Notlar:
- Frontend bileşeni "poly-link-field" olarak ayarlanır
- TYPE_POLY_LINK sabiti ile alan türü belirtilir
- Polimorfik ilişkiler karmaşık olabilir, dikkatli tasarım gerekir
func RichText ¶
Bu fonksiyon, zengin metin editörü (WYSIWYG - What You See Is What You Get) alanı oluşturur.
Kullanım Senaryosu: - Blog yazıları, ürün açıklamaları, HTML içeriği gibi zengin metin girişi için - Metin biçimlendirmesi (bold, italic, underline), listeler, linkler vb. destekler - Genellikle TinyMCE, Quill veya benzer editörler ile entegre edilir
Parametreler:
- name: Alanın görüntü adı (örn: "İçerik", "Açıklama")
- attribute: İsteğe bağlı veritabanı sütun adı
Dönüş Değeri:
- *Schema: Yapılandırılmış zengin metin alan şeması pointer'ı
Örnek Kullanım:
contentField := RichText("İçerik")
descField := RichText("Ürün Açıklaması", "product_description")
Önemli Notlar:
- Frontend bileşeni "richtext-field" olarak ayarlanır
- TYPE_RICHTEXT sabiti ile alan türü belirtilir
- HTML sanitization gerekli olabilir (XSS koruması için)
func Select ¶
Bu fonksiyon, standart seçim listesi oluşturur ve yapılandırır.
Kullanım Senaryosu: - Önceden tanımlanmış seçeneklerden birini seçmek için - Durum, kategori, tür gibi sınırlı sayıda seçeneği olan alanlar için - Dropdown veya select bileşeni ile seçim yapılır
Parametreler:
- name: Alanın görüntü adı (örn: "Durum", "Tür")
- attribute: İsteğe bağlı veritabanı sütun adı
Dönüş Değeri:
- *Schema: Yapılandırılmış seçim alan şeması pointer'ı
Örnek Kullanım:
statusSelect := Select("Durum")
typeSelect := Select("Tür", "type_id")
Önemli Notlar:
- Frontend bileşeni "select-field" olarak ayarlanır
- TYPE_SELECT sabiti ile alan türü belirtilir
- Seçenekler Props haritasına "options" anahtarı ile eklenebilir
- Varsayılan değer ayarlanabilir
func Stack ¶
Stack, birden fazla alanı tek bir konteynerde göstermek için kullanılan display odaklı bir field oluşturur.
Bu fonksiyon özellikle Display callback'lerinde kullanılır:
fields.Text("Sizes", "sizes").Display(func(value interface{}, item interface{}) core.Element {
return fields.Stack([]core.Element{
fields.Badge("10").WithProps("variant", "secondary"),
fields.Badge("20").WithProps("variant", "secondary"),
})
})
func Switch ¶
Bu fonksiyon, boolean değerler için switch/toggle bileşeni oluşturur ve yapılandırır.
Kullanım Senaryosu: - Aktif/Pasif, Evet/Hayır, Açık/Kapalı gibi boolean değerleri için - Toggle switch bileşeni ile kolay seçim yapılabilir - Genellikle veritabanında 0/1 veya true/false olarak saklanır
Parametreler:
- name: Alanın görüntü adı (örn: "Aktif", "Yayınla")
- attribute: İsteğe bağlı veritabanı sütun adı
Dönüş Değeri:
- *Schema: Yapılandırılmış switch alan şeması pointer'ı
Örnek Kullanım:
activeSwitch := Switch("Aktif")
publishSwitch := Switch("Yayınla", "is_published")
Önemli Notlar:
- Frontend bileşeni "switch-field" olarak ayarlanır
- TYPE_BOOLEAN sabiti ile alan türü belirtilir
- Genellikle checkbox yerine toggle switch kullanılır
- Varsayılan değer (true/false) ayarlanabilir
func Tel ¶
Bu fonksiyon, telefon numarası giriş alanı oluşturur ve yapılandırır.
Kullanım Senaryosu: - Müşteri telefon numarası, iletişim numarası gibi telefon girişi için - Genellikle metin input olarak render edilir, ancak telefon formatı doğrulaması yapılabilir - Ülkeye göre farklı telefon formatları desteklenebilir
Parametreler:
- name: Alanın görüntü adı (örn: "Telefon", "Cep Telefonu")
- attribute: İsteğe bağlı veritabanı sütun adı
Dönüş Değeri:
- *Schema: Yapılandırılmış telefon alan şeması pointer'ı
Örnek Kullanım:
phoneField := Tel("Telefon")
mobileField := Tel("Cep Telefonu", "mobile_phone")
Önemli Notlar:
- Frontend bileşeni "text-field" olarak ayarlanır (genellikle text input kullanılır)
- TYPE_TEL sabiti ile alan türü belirtilir
- Backend'de regex veya libphonenumber gibi kütüphaneler ile doğrulama yapılmalı
- Uluslararası format desteği eklenebilir
func Text ¶
Bu fonksiyon, standart metin giriş alanı (input type="text") oluşturur ve yapılandırır.
Kullanım Senaryosu: - Kullanıcı adı, başlık, kısa açıklama gibi tek satırlı metin girişi için - Basit string veri türü için en yaygın kullanılan alan - Maksimum uzunluk kısıtlaması eklenebilir
Parametreler:
- name: Alanın görüntü adı (örn: "Başlık", "Kullanıcı Adı")
- attribute: İsteğe bağlı veritabanı sütun adı
Dönüş Değeri:
- *Schema: Yapılandırılmış metin alan şeması pointer'ı
Örnek Kullanım:
titleField := Text("Başlık")
usernameField := Text("Kullanıcı Adı", "username")
emailField := Text("E-posta", "email_address")
Önemli Notlar:
- Frontend bileşeni "text-field" olarak ayarlanır
- TYPE_TEXT sabiti ile alan türü belirtilir
- Method chaining ile ek özellikler eklenebilir (örn: .Required(), .MaxLength(100))
func Textarea ¶
Bu fonksiyon, çok satırlı metin giriş alanı (textarea) oluşturur ve yapılandırır.
Kullanım Senaryosu: - Uzun açıklamalar, notlar, biyografi gibi çok satırlı metin girişi için - Sabit yükseklikte veya dinamik olarak genişleyebilen textarea - Markdown veya HTML desteği eklenebilir
Parametreler:
- name: Alanın görüntü adı (örn: "Açıklama", "Notlar")
- attribute: İsteğe bağlı veritabanı sütun adı
Dönüş Değeri:
- *Schema: Yapılandırılmış textarea alan şeması pointer'ı
Örnek Kullanım:
descField := Textarea("Açıklama")
bioField := Textarea("Biyografi", "biography")
Önemli Notlar:
- Frontend bileşeni "textarea-field" olarak ayarlanır
- TYPE_TEXTAREA sabiti ile alan türü belirtilir
- Satır sayısı (rows) özelliği Props haritasına eklenebilir
func Video ¶
Bu fonksiyon, video yükleme alanı oluşturur ve yapılandırır.
Kullanım Senaryosu: - Ürün tanıtım videoları, eğitim videoları, demo videoları gibi video dosyaları yüklemek için - Genellikle MP4, WebM, OGG gibi video formatlarını destekler - Video ön izlemesi ve oynatıcı entegrasyonu yapılabilir
Parametreler:
- name: Alanın görüntü adı (örn: "Tanıtım Videosu", "Demo")
- attribute: İsteğe bağlı veritabanı sütun adı
Dönüş Değeri:
- *Schema: Yapılandırılmış video alan şeması pointer'ı
Örnek Kullanım:
videoField := Video("Tanıtım Videosu")
demoField := Video("Demo Videosu", "demo_video")
Önemli Notlar:
- Frontend bileşeni "file-field" olarak ayarlanır
- TYPE_VIDEO sabiti ile alan türü belirtilir
- Dosya boyutu kısıtlaması eklenebilir (videolar genellikle büyük dosyalardır)
- Video codec ve format doğrulaması yapılabilir
func (*Schema) Accept ¶
Accept, kabul edilen MIME tiplerini ayarlar.
Bu metod, hangi dosya tiplerinin yüklenebileceğini belirler. Frontend'de dosya seçici bu tiplere göre filtrelenir.
Parametreler ¶
- mimeTypes: Kabul edilen MIME tipleri (variadic)
Döndürür ¶
- core.Element: Zincirleme çağrılar için Schema pointer'ı
Yaygın MIME Tipleri ¶
- Resimler: "image/jpeg", "image/png", "image/gif", "image/webp"
- Dökümanlar: "application/pdf", "application/msword"
- Video: "video/mp4", "video/webm"
- Audio: "audio/mpeg", "audio/wav"
Kullanım Senaryoları ¶
- Profil fotoğrafı yükleme
- Döküman yükleme
- Medya dosyası yükleme
Örnek ¶
field := File("avatar", "Profil Fotoğrafı").
Accept("image/jpeg", "image/png", "image/webp").
MaxSize(5 * 1024 * 1024) // 5MB
func (*Schema) AddValidationRule ¶
AddValidationRule, alana bir doğrulama kuralı ekler.
Bu metod, özel veya hazır doğrulama kurallarını alana eklemek için kullanılır. ValidationRule interface'ini implement eden herhangi bir kural eklenebilir.
Parametreler ¶
- rule: Eklenecek doğrulama kuralı (ValidationRule interface'ini implement etmeli)
Döndürür ¶
- core.Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- Özel doğrulama kuralları ekleme
- Hazır kural fonksiyonlarını kullanma
- Çoklu doğrulama kuralları birleştirme
Örnek ¶
field := Text("age", "Yaş").
AddValidationRule(Min(18)).
AddValidationRule(Max(100))
func (*Schema) AllowCustomCurrency ¶
AllowCustomCurrency, money field için custom currency girişine izin verip vermeyeceğini ayarlar.
func (*Schema) AsPivot ¶
AsPivot, alanı pivot field olarak işaretler.
Bu metod, alanın bir pivot tablo alanı olduğunu belirtir. Many-to-many ilişkilerde ara tablodaki ekstra alanlar için kullanılır.
Döndürür ¶
- core.Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- Rol-izin ilişkisinde izin tarihi
- Ürün-kategori ilişkisinde sıralama
- Kullanıcı-grup ilişkisinde katılma tarihi
Örnek ¶
field := DateTime("assigned_at", "Atanma Tarihi").
AsPivot().
WithPivotResource("user_roles")
func (*Schema) AutoOptions ¶
AutoOptions, alan için otomatik seçenek yükleme ayarlar.
Bu metod, ilişkili model'den otomatik olarak seçeneklerin yüklenmesini sağlar. BelongsTo, HasOne gibi ilişki alanları için kullanılır.
Parametreler ¶
- displayField: Seçeneklerde gösterilecek alan adı
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- İlişkili model seçenekleri
- Dinamik seçenek listeleri
- Veritabanından seçenek yükleme
Örnek ¶
field := BelongsTo("category_id", "Kategori").AutoOptions("name")
func (*Schema) CanSee ¶
func (s *Schema) CanSee(fn VisibilityFunc) Element
CanSee, alan için görünürlük callback'i ayarlar.
Bu metod, alanın dinamik olarak gösterilip gizlenmesini sağlar. Callback, kullanıcı izinlerine, rol'lere veya diğer koşullara göre çalışabilir.
Parametreler ¶
- fn: Görünürlük kontrolü yapan fonksiyon
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- İzin tabanlı görünürlük
- Rol tabanlı görünürlük
- Koşullu alan gösterimi
- Dinamik form yapıları
Örnek ¶
field := Text("salary", "Maaş").CanSee(func(ctx *core.ResourceContext) bool {
return ctx.User.IsAdmin()
})
func (*Schema) CreationRules ¶
func (*Schema) Currencies ¶
Currencies, money field için izin verilen para birimi enum listesini ayarlar.
func (*Schema) Currency ¶
Currency, money field için para birimi kodunu ayarlar (örn: "USD", "TRY").
func (*Schema) CurrencyEnum ¶
CurrencyEnum, money field için para birimini enum ile ayarlar.
func (*Schema) CustomCurrencies ¶
CustomCurrencies, money field için ek özel para birimi kodları tanımlar.
func (*Schema) Default ¶
Default, alan için varsayılan değer ayarlar.
Bu metod, alanın başlangıç değerini belirler. Form ilk açıldığında bu değer gösterilir.
Parametreler ¶
- value: Varsayılan değer
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- Form başlangıç değerleri
- Önerilen değerler
- Varsayılan seçimler
Örnek ¶
field := Select("status", "Durum").Default("active")
func (*Schema) DependsOn ¶
DependsOn, alanın bağımlı olduğu diğer alanları belirtir.
Bu metod, alanın görünürlüğünün veya davranışının diğer alanlara bağlı olduğunu belirtir. Bağımlı alanlar değiştiğinde, bu alan da güncellenir.
Parametreler ¶
- fields: Bağımlı olunan alan adları (variadic)
Döndürür ¶
- core.Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- Cascade seçim alanları (ülke -> şehir -> ilçe)
- Koşullu alan gösterimi
- Dinamik form yapıları
- İlişkili alan güncellemeleri
Örnek ¶
field := Select("city", "Şehir").
DependsOn("country").
When("country", "=", "TR")
func (*Schema) Disabled ¶
Disabled, alanı devre dışı bırakır.
Devre dışı alanlar, kullanıcı tarafından ne düzenlenebilir ne de etkileşime girebilir. ReadOnly'den farklı olarak, görsel olarak da devre dışı görünür.
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
ReadOnly vs Disabled ¶
- **ReadOnly**: Görüntülenebilir, kopyalanabilir, ancak düzenlenemez
- **Disabled**: Tamamen etkileşimsiz, genellikle gri/soluk görünür
Kullanım Senaryoları ¶
- Koşullu olarak devre dışı bırakılan alanlar
- İzin kontrolü gerektiren alanlar
- Bağımlı alanlar (başka bir alan seçilene kadar)
Örnek ¶
field := Select("city", "Şehir").Disabled()
func (*Schema) Display ¶
Display, alan için özel görüntüleme callback'i ayarlar.
Bu metod, alanın değerinin nasıl görüntüleneceğini özelleştirmeye olanak tanır. Callback, alan değerini ve ilgili kaydı alır; görüntülenecek değeri döner.
Parametreler ¶
- fn: Görüntüleme işlemini yapan fonksiyon. Desteklenen imzalar:
- func(value interface{}) string
- func(value interface{}) interface{}
- func(value interface{}, item interface{}) string
- func(value interface{}, item interface{}) interface{}
Döndürür ¶
- core.Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- Tarih formatı özelleştirme
- Para birimi formatı
- Boolean değerleri metin olarak gösterme
- Enum değerlerini açıklayıcı metne çevirme
Örnek ¶
field := Boolean("is_active", "Aktif").Display(func(value interface{}, item interface{}) interface{} {
if value.(bool) {
return "Aktif ✓"
}
return "Pasif ✗"
})
func (*Schema) DisplayAs ¶
DisplayAs, alan için görüntüleme format string'i ayarlar.
Bu metod, alanın değerinin belirli bir formatta görüntülenmesini sağlar. Format string'i, frontend tarafından yorumlanır.
Parametreler ¶
- format: Görüntüleme format string'i
Döndürür ¶
- core.Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- Tarih formatı belirleme ("DD/MM/YYYY")
- Para birimi formatı ("$0,0.00")
- Yüzde formatı ("%0.2f")
Örnek ¶
field := Number("price", "Fiyat").DisplayAs("$0,0.00")
func (*Schema) DisplayUsingLabels ¶
DisplayUsingLabels, alanın etiketler kullanarak görüntüleneceğini belirtir.
Bu metod, select, radio gibi seçim alanlarında değer yerine etiketin gösterilmesini sağlar. Örneğin, "1" yerine "Aktif" gösterilir.
Döndürür ¶
- core.Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- Select alanlarında etiket gösterimi
- Enum değerlerinin açıklayıcı gösterimi
- İlişkili kayıtların isim gösterimi
Örnek ¶
field := Select("status", "Durum").
Options([]map[string]interface{}{
{"value": 1, "label": "Aktif"},
{"value": 0, "label": "Pasif"},
}).
DisplayUsingLabels()
func (*Schema) Email ¶
Email, e-posta doğrulama kuralı ekler.
Bu metod, alanın geçerli bir e-posta adresi içermesini zorunlu kılar. RFC 5322 standardına göre e-posta formatı kontrol edilir.
Döndürür ¶
- core.Element: Zincirleme çağrılar için Schema pointer'ı
Doğrulama Kuralları ¶
- @ işareti içermeli
- Geçerli domain formatı
- Geçerli local part formatı
Kullanım Senaryoları ¶
- Kullanıcı kayıt formları
- İletişim formları
- Profil güncelleme formları
Örnek ¶
field := Text("email", "E-posta").Required().Email()
func (*Schema) Exists ¶
Exists, varlık doğrulama kuralı ekler.
Bu metod, alanın değerinin belirtilen tabloda mevcut olmasını zorunlu kılar. Foreign key ilişkileri için kullanılır.
Parametreler ¶
- table: Kontrol edilecek tablo adı
- column: Kontrol edilecek sütun adı
Döndürür ¶
- core.Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- Foreign key doğrulama
- İlişkili kayıt kontrolü
- Referans doğrulama
Önemli Notlar ¶
- Silinen kayıtlar (soft delete) için dikkatli kullanılmalı
- Performans için veritabanı indeksi önerilir
- NULL değerler için ayrıca Nullable() kullanılmalı
Örnek ¶
field := BelongsTo("category_id", "Kategori").
Required().
Exists("categories", "id")
func (*Schema) Extract ¶
func (s *Schema) Extract(resource interface{})
Extract, verilen resource'dan veri çıkarır ve alanı doldurur.
Bu metod, reflection kullanarak resource'dan alan değerini çıkarır. Resource bir struct veya map olabilir. Struct için, alan adı veya JSON tag'i kullanılarak field bulunur. Map için, key kullanılarak değer alınır.
Özel Durumlar ¶
- **ID Suffix Uyumsuzluğu**: "author_id" gibi bir key için, önce "AuthorId" aranır, bulunamazsa "AuthorID" aranır (Go naming convention)
- **JSON Tag Desteği**: Struct field'ları JSON tag'leri ile de eşleştirilebilir
- **Nil Güvenliği**: Resource nil ise hiçbir işlem yapılmaz
Parametreler:
- resource: Veri çıkarılacak kaynak (struct veya map)
Örnek:
type User struct {
Name string `json:"name"`
Email string `json:"email"`
}
user := &User{Name: "John", Email: "[email protected]"}
schema := &Schema{Key: "name"}
schema.Extract(user)
// schema.Data artık "John" değerini içerir
func (*Schema) Fields ¶
Fields, repeater için alt alanları ayarlar.
Bu metod, tekrarlayan grup içindeki alanları belirler. Her tekrar, bu alanların bir kopyasını içerir.
Parametreler ¶
- fields: Tekrarlayan alan listesi (variadic)
Döndürür ¶
- core.Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- Telefon numaraları listesi
- E-posta adresleri listesi
- Ürün varyantları
- Adres bilgileri
Örnek ¶
field := Repeater("phones", "Telefon Numaraları").
Fields(
Text("number", "Numara").Required(),
Select("type", "Tip").Options([]string{"Ev", "İş", "Mobil"}),
).
MinRepeats(1).
MaxRepeats(5)
func (*Schema) Filterable ¶
Filterable, alanın filtrelenebilir olduğunu belirtir.
Filterable alanlar, liste görünümünde filtre seçenekleri sunar. Kullanıcılar bu alana göre kayıtları filtreleyebilir.
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- Durum alanları (aktif/pasif)
- Kategori alanları
- Tarih aralıkları
- Sayısal aralıklar
Örnek ¶
field := Select("status", "Durum").Filterable()
func (*Schema) GetAcceptedMimeTypes ¶
GetAcceptedMimeTypes, kabul edilen MIME tiplerini döner.
Döndürür ¶
- []string: Kabul edilen MIME tipleri listesi (boş slice olabilir)
Örnek ¶
mimeTypes := field.GetAcceptedMimeTypes()
for _, mime := range mimeTypes {
fmt.Println("Accepted:", mime)
}
func (*Schema) GetAutoCompleteURL ¶
GetAutoCompleteURL, otomatik tamamlama URL'ini döner.
Döndürür ¶
- string: Autocomplete API endpoint'i
func (*Schema) GetAutoOptionsConfig ¶
func (s *Schema) GetAutoOptionsConfig() core.AutoOptionsConfig
GetAutoOptionsConfig, alanın auto options yapılandırmasını döner.
Döndürür ¶
- core.AutoOptionsConfig: Auto options yapılandırması
func (*Schema) GetBadgeVariant ¶
GetBadgeVariant, badge varyantını döner.
Döndürür ¶
- string: Badge varyantı (örn. "solid", "outline")
func (*Schema) GetContext ¶
func (s *Schema) GetContext() ElementContext
GetContext, alanın görüntülendiği bağlamı döndürür. Bağlam, alanın nerede gösterilmesi gerektiğini belirtir (form, list, detail).
Döndürür:
- Görüntüleme bağlamı (ElementContext)
func (*Schema) GetCreationValidationRules ¶
func (s *Schema) GetCreationValidationRules() []interface{}
func (*Schema) GetCustomValidators ¶
func (s *Schema) GetCustomValidators() []interface{}
GetCustomValidators, özel doğrulayıcı fonksiyonlarını döner.
Döndürür ¶
- []interface{}: Özel doğrulayıcı fonksiyonları listesi
Örnek ¶
validators := field.GetCustomValidators()
for _, validator := range validators {
// Doğrulayıcıyı çalıştır
}
func (*Schema) GetDependencies ¶
GetDependencies, alanın bağımlı olduğu diğer alanların listesini döner.
Bu metod, Props içindeki "dependencies" anahtarını kontrol eder. Bağımlılık yönetimi için kullanılır.
Döndürür ¶
- []string: Bağımlı alan adları listesi (boş slice olabilir)
Kullanım Senaryoları ¶
- Dinamik form alanları
- Koşullu alan gösterimi
- Cascade seçim alanları
- Bağımlılık grafiği oluşturma
Örnek ¶
deps := field.GetDependencies()
for _, dep := range deps {
// Bağımlı alanı kontrol et
}
func (*Schema) GetDependencyCallback ¶
func (s *Schema) GetDependencyCallback(context string) DependencyCallbackFunc
GetDependencyCallback, bağlama göre uygun callback'i döner.
Bu metod, verilen bağlama (create/update) göre uygun callback fonksiyonunu döner. Bağlama özel callback yoksa, genel callback döner.
Parametreler ¶
- context: Bağlam string'i ("create" veya "update")
Döndürür ¶
- DependencyCallbackFunc: Uygun callback fonksiyonu (nil olabilir)
Örnek ¶
callback := field.GetDependencyCallback("create")
if callback != nil {
result := callback(dependencies, ctx)
}
func (*Schema) GetDependencyRules ¶
GetDependencyRules, bağımlılık kurallarını döner.
Döndürür ¶
- map[string]interface{}: Bağımlılık kuralları map'i (boş map olabilir)
Örnek ¶
rules := field.GetDependencyRules()
for field, rule := range rules {
fmt.Printf("Field %s has rule: %v\n", field, rule)
}
func (*Schema) GetDisplayCallback ¶
func (s *Schema) GetDisplayCallback() func(value interface{}, item interface{}) interface{}
GetDisplayCallback, görüntüleme callback fonksiyonunu döner.
Döndürür ¶
- func(value interface{}, item interface{}) interface{}: Display callback fonksiyonu (nil olabilir)
Örnek ¶
callback := field.GetDisplayCallback()
if callback != nil {
displayValue := callback(value, item)
}
func (*Schema) GetDisplayedAs ¶
GetDisplayedAs, görüntüleme format string'ini döner.
Döndürür ¶
- string: Format string'i
func (*Schema) GetEditorLanguage ¶
GetEditorLanguage, editör dilini döner.
Döndürür ¶
- string: Dil kodu (örn. "tr", "en")
func (*Schema) GetEditorTheme ¶
GetEditorTheme, editör temasını döner.
Döndürür ¶
- string: Tema adı (örn. "modern", "dark")
func (*Schema) GetEditorType ¶
GetEditorType, editör tipini döner.
Döndürür ¶
- string: Editör tipi (örn. "tinymce", "quill", "ckeditor")
func (*Schema) GetGormConfig ¶
func (s *Schema) GetGormConfig() *GormConfig
GetGormConfig, alanın GORM yapılandırmasını döner.
func (*Schema) GetKey ¶
GetKey, alanın benzersiz tanımlayıcısını döndürür. Key, alanı resource model'indeki bir field'a eşlemek için kullanılır.
Döndürür:
- Alanın benzersiz tanımlayıcısı (key)
func (*Schema) GetMaxFileSize ¶
GetMaxFileSize, maksimum dosya boyutunu döner.
Döndürür ¶
- int64: Maksimum dosya boyutu (byte cinsinden)
Örnek ¶
maxSize := field.GetMaxFileSize()
fmt.Printf("Max size: %d MB\n", maxSize/(1024*1024))
func (*Schema) GetMaxRepeats ¶
GetMaxRepeats, maksimum tekrar sayısını döner.
Döndürür ¶
- int: Maksimum tekrar sayısı
func (*Schema) GetMetadata ¶
GetMetadata, alan hakkında metadata bilgilerini döner.
Bu metod, alanın tüm özelliklerini içeren bir map döner. API yanıtları, debugging ve introspection için kullanılır.
Döndürür ¶
- map[string]interface{}: Alan metadata'sı
İçerilen Bilgiler ¶
- name: Görünen ad
- key: Benzersiz tanımlayıcı
- view: Frontend bileşeni
- type: Veri tipi
- context: Görüntüleme bağlamı
- read_only: Salt okunur durumu
- disabled: Devre dışı durumu
- immutable: Değiştirilemez durumu
- required: Zorunlu durumu
- nullable: Boş bırakılabilir durumu
- filterable: Filtrelenebilir durumu
- sortable: Sıralanabilir durumu
- searchable: Aranabilir durumu
- stacked: Yığılmış durumu
- text_align: Metin hizalama
- dependencies: Bağımlılıklar
- props: Ekstra özellikler
Örnek ¶
metadata := field.GetMetadata()
fmt.Printf("Field: %s, Type: %s\n", metadata["name"], metadata["type"])
func (*Schema) GetMinCharsForSuggestions ¶
GetMinCharsForSuggestions, öneri için minimum karakter sayısını döner.
Döndürür ¶
- int: Minimum karakter sayısı
func (*Schema) GetMinRepeats ¶
GetMinRepeats, minimum tekrar sayısını döner.
Döndürür ¶
- int: Minimum tekrar sayısı
func (*Schema) GetModifyCallback ¶
GetModifyCallback, alanın modify callback'ini döner.
Döndürür ¶
- func: Modify callback fonksiyonu (nil olabilir)
func (*Schema) GetName ¶
GetName, bu element'in görünen adını döndürür.
Name, element'in kullanıcı arayüzünde gösterilecek insan okunabilir adıdır. Genellikle form label'ı veya tablo başlığı olarak kullanılır.
Döndürür:
- Element'in görünen adı (örn: "Name", "Email", "Author")
Örnek:
field := fields.Text("Name", "name")
name := field.GetName() // "Name"
func (*Schema) GetPivotResourceName ¶
GetPivotResourceName, pivot resource adını döner.
Döndürür ¶
- string: Pivot resource adı
func (*Schema) GetRepeaterFields ¶
GetRepeaterFields, repeater alt alanlarını döner.
Döndürür ¶
- []Element: Alt alan listesi
Örnek ¶
fields := field.GetRepeaterFields()
for _, f := range fields {
fmt.Println(f.GetKey())
}
func (*Schema) GetResolveCallback ¶
func (s *Schema) GetResolveCallback() func(value interface{}, item interface{}, c *fiber.Ctx) interface{}
GetResolveCallback, alanın resolve callback'ini döner.
Döndürür ¶
- func: Resolve callback fonksiyonu (nil olabilir)
func (*Schema) GetResolveHandle ¶
GetResolveHandle, resolve handle değerini döner.
Bu metod, client-side bileşen etkileşimi için kullanılan handle'ı döner.
Döndürür ¶
- string: Resolve handle değeri
Örnek ¶
handle := field.GetResolveHandle()
if handle != "" {
// Handle'ı kullan
}
func (*Schema) GetStatusColors ¶
GetStatusColors, durum renk eşleştirmesini döner.
Döndürür ¶
- map[string]string: Durum-renk eşleştirme map'i (boş map olabilir)
Örnek ¶
colors := field.GetStatusColors()
if color, ok := colors["active"]; ok {
fmt.Println("Active color:", color)
}
func (*Schema) GetStorageCallback ¶
func (s *Schema) GetStorageCallback() StorageCallbackFunc
GetStorageCallback, alanın depolama callback'ini döner.
Döndürür ¶
- StorageCallbackFunc: Depolama callback fonksiyonu (nil olabilir)
func (*Schema) GetStorageDisk ¶
GetStorageDisk, depolama disk adını döner.
Döndürür ¶
- string: Depolama disk adı (örn. "local", "s3", "gcs")
Örnek ¶
disk := field.GetStorageDisk()
func (*Schema) GetStoragePath ¶
GetStoragePath, depolama yolunu döner.
Döndürür ¶
- string: Depolama yolu (örn. "uploads/avatars")
Örnek ¶
path := field.GetStoragePath()
func (*Schema) GetSuggestions ¶
GetSuggestions, verilen sorgu için önerileri döner.
Bu metod, SuggestionsCallback varsa onu çağırır, yoksa mevcut Suggestions listesini döner.
Parametreler ¶
- query: Arama sorgusu
Döndürür ¶
- []interface{}: Öneri listesi
Örnek ¶
suggestions := field.GetSuggestions("john")
for _, s := range suggestions {
fmt.Println(s)
}
func (*Schema) GetSuggestionsCallback ¶
GetSuggestionsCallback, öneri callback fonksiyonunu döner.
Döndürür ¶
- func(string) []interface{}: Suggestions callback fonksiyonu (nil olabilir)
Örnek ¶
callback := field.GetSuggestionsCallback()
if callback != nil {
suggestions := callback("query")
}
func (*Schema) GetType ¶
func (s *Schema) GetType() core.ElementType
GetType, bu element'in veri tipini döndürür.
Type, element'in veri tipini belirler ve validation, formatting ve OpenAPI schema oluşturma için kullanılır. Örneğin: TYPE_TEXT, TYPE_NUMBER, TYPE_BOOLEAN, TYPE_DATE
Döndürür:
- Element'in veri tipi (core.ElementType)
Örnek:
field := fields.Text("Name", "name")
fieldType := field.GetType() // core.TYPE_TEXT
func (*Schema) GetUpdateValidationRules ¶
func (s *Schema) GetUpdateValidationRules() []interface{}
func (*Schema) GetUploadCallback ¶
GetUploadCallback, dosya yükleme callback fonksiyonunu döner.
Döndürür ¶
- func: Upload callback fonksiyonu (nil olabilir)
Örnek ¶
callback := field.GetUploadCallback()
if callback != nil {
err := callback(file, item)
}
func (*Schema) GetValidationRules ¶
func (s *Schema) GetValidationRules() []interface{}
GetValidationRules, doğrulama kurallarını döner.
Döndürür ¶
- []interface{}: Doğrulama kuralları listesi
Örnek ¶
rules := field.GetValidationRules()
for _, rule := range rules {
// Kuralı uygula
}
func (*Schema) GetView ¶
GetView, alanın görünüm tipini döndürür. View tipi, alanın UI'da nasıl render edileceğini belirler.
Döndürür:
- Görünüm tipi (örn. "text-field", "email-field", "select-field")
func (*Schema) Gorm ¶
func (s *Schema) Gorm(config *GormConfig) Element
Gorm, alan için GORM veritabanı yapılandırmasını ayarlar. Bu metod, migration ve model oluşturma için kullanılır.
func (*Schema) GormAutoIncrement ¶
GormAutoIncrement, alanı otomatik artış olarak işaretler.
func (*Schema) GormComment ¶
GormComment, alan için veritabanı yorumu ekler.
func (*Schema) GormDefault ¶
GormDefault, alan için varsayılan değer belirler.
func (*Schema) GormForeignKey ¶
GormForeignKey, alan için foreign key ilişkisi tanımlar.
func (*Schema) GormFullTextIndex ¶
GormFullTextIndex, alan için fulltext indeks oluşturur.
func (*Schema) GormOnDelete ¶
GormOnDelete, foreign key için ON DELETE davranışını belirler.
func (*Schema) GormOnUpdate ¶
GormOnUpdate, foreign key için ON UPDATE davranışını belirler.
func (*Schema) GormPrimaryKey ¶
GormPrimaryKey, alanı birincil anahtar olarak işaretler.
func (*Schema) GormSnowflake ¶
GormSnowflake, Snowflake tipinde ID kullanır.
func (*Schema) GormSoftDelete ¶
GormSoftDelete, alan için soft delete desteği ekler.
func (*Schema) GormUniqueIndex ¶
GormUniqueIndex, alan için benzersiz indeks oluşturur.
func (*Schema) HasGormConfig ¶
HasGormConfig, alanın GORM yapılandırması olup olmadığını kontrol eder.
func (*Schema) HelpText ¶
HelpText, alan için yardım metni ayarlar.
HelpText, alanın altında gösterilen açıklayıcı veya yönlendirici metindir. Kullanıcıya alan hakkında ek bilgi verir.
Parametreler ¶
- helpText: Yardım metni
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- Format açıklaması (örn. "DD/MM/YYYY formatında")
- Karakter limiti bilgisi
- Güvenlik uyarıları
- Kullanım önerileri
Örnek ¶
field := Password("password", "Şifre").
HelpText("En az 8 karakter, bir büyük harf ve bir rakam içermelidir")
func (*Schema) HideNumberControls ¶
HideNumberControls, number input alanındaki artı/eksi butonlarını gizler.
Bu metod ShowNumberControls(false) için kısa yoldur.
func (*Schema) HideOnApi ¶
HideOnApi, alanı external API yanıtlarında gizler.
Bu metod, alanın external API çıktısında yer almamasını sağlar.
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
Örnek ¶
field := Text("secret", "secret").HideOnApi()
func (*Schema) HideOnCreate ¶
HideOnCreate, alanı oluşturma formunda gizler.
Bu metod, alanın yeni kayıt oluşturma formunda gizlenmesini sağlar. Genellikle otomatik oluşturulan alanlar (ID, timestamps) için kullanılır.
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
Örnek ¶
field := Text("id", "ID").HideOnCreate()
func (*Schema) HideOnDetail ¶
HideOnDetail, alanı detay görünümünde gizler.
Bu metod, alanın kayıt detay sayfasında gizlenmesini sağlar. Genellikle sadece form için gerekli olan alanlar için kullanılır.
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
Örnek ¶
field := Password("password", "Şifre").HideOnDetail()
func (*Schema) HideOnGrid ¶
HideOnGrid, alanı grid görünümünde gizler.
func (*Schema) HideOnList ¶
HideOnList, alanı liste görünümünde gizler.
Bu metod, alanın tablo/liste görünümünde gizlenmesini sağlar. Genellikle uzun metinler veya hassas bilgiler için kullanılır.
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
Örnek ¶
field := Textarea("bio", "Biyografi").HideOnList()
func (*Schema) HideOnUpdate ¶
HideOnUpdate, alanı güncelleme formunda gizler.
Bu metod, alanın kayıt güncelleme formunda gizlenmesini sağlar. Genellikle değiştirilmemesi gereken alanlar için kullanılır.
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
Örnek ¶
field := Text("username", "Kullanıcı Adı").HideOnUpdate()
func (*Schema) Immutable ¶
Immutable, alanı değiştirilemez olarak işaretler.
Immutable alanlar, oluşturulduktan sonra asla değiştirilemez. Genellikle oluşturma formunda gösterilir, güncelleme formunda gizlenir veya salt okunur olur.
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- Kullanıcı adı (username)
- E-posta adresi (bazı sistemlerde)
- Benzersiz tanımlayıcılar
- Kayıt oluşturma zamanı
Örnek ¶
field := Text("username", "Kullanıcı Adı").Immutable()
func (*Schema) IsConditionallyVisible ¶
IsConditionallyVisible, alanın kayıt değerlerine göre görünür olup olmadığını belirler.
Bu metod, VisibilityCallback varsa onu çağırır, yoksa true döner. Dinamik görünürlük kontrolü için kullanılır.
Parametreler ¶
- item: Kontrol edilecek kayıt
Döndürür ¶
- bool: Alanın görünür olup olmadığı
Kullanım Senaryoları ¶
- Kayıt durumuna göre alan gösterimi
- Kullanıcı rolüne göre alan gösterimi
- Değer bazlı koşullu görünürlük
Örnek ¶
if field.IsConditionallyVisible(user) {
// Alanı göster
}
func (*Schema) IsHidden ¶
func (s *Schema) IsHidden(ctx VisibilityContext) bool
IsHidden, alanın belirli bir görünürlük bağlamında gizli olup olmadığını kontrol eder.
Bu metod, IsVisibleInContext metodunun tersini döner. Görünürlük kontrolü için kullanılır.
Parametreler ¶
- ctx: Görünürlük bağlamı (ContextIndex, ContextDetail, ContextCreate, ContextUpdate, ContextPreview)
Döndürür ¶
- bool: Alanın gizli olup olmadığı
Kullanım Senaryoları ¶
- Koşullu alan gösterimi
- Bağlam bazlı görünürlük kontrolü
- Form ve liste filtreleme
Örnek ¶
if field.IsHidden(ContextCreate) {
// Alanı oluşturma formunda gösterme
}
func (*Schema) IsPivot ¶
IsPivot, alanın pivot field olup olmadığını kontrol eder.
Döndürür ¶
- bool: Pivot field ise true
Örnek ¶
if field.IsPivot() {
resource := field.GetPivotResourceName()
}
func (*Schema) IsRepeaterField ¶
IsRepeaterField, alanın bir repeater field olup olmadığını kontrol eder.
Döndürür ¶
- bool: Repeater field ise true
Örnek ¶
if field.IsRepeaterField() {
fields := field.GetRepeaterFields()
}
func (*Schema) IsSearchable ¶
IsSearchable, alanın aranabilir olup olmadığını kontrol eder.
Döndürür ¶
- bool: Alanın aranabilir olup olmadığı
Örnek ¶
if field.IsSearchable() {
// Arama sorgusu oluştur
}
func (*Schema) IsVisible ¶
func (s *Schema) IsVisible(ctx *core.ResourceContext) bool
IsVisible, alanın belirli bir bağlamda görünür olup olmadığını kontrol eder.
Bu metod, VisibilityCallback varsa onu çağırır, yoksa true döner. Dinamik görünürlük kontrolü için kullanılır.
Parametreler ¶
- ctx: Resource bağlamı (kullanıcı, izinler, vb.)
Döndürür ¶
- bool: Alanın görünür olup olmadığı
Örnek ¶
if field.IsVisible(ctx) {
// Alanı göster
}
func (*Schema) IsVisibleInContext ¶
func (s *Schema) IsVisibleInContext(ctx VisibilityContext) bool
IsVisibleInContext, alanın belirli bir bağlamda görünür olup olmadığını kontrol eder.
Bu metod, ElementContext değerlerine göre görünürlük kontrolü yapar. Her bağlam için farklı kurallar uygulanır.
Parametreler ¶
- ctx: Görünürlük bağlamı
Döndürür ¶
- bool: Alanın görünür olup olmadığı
Bağlam Kuralları ¶
**ContextIndex (Liste Görünümü)**:
- HIDE_ON_LIST ise gizli
- ONLY_ON_DETAIL ise gizli
- ONLY_ON_FORM ise gizli
- Diğer durumlarda görünür
**ContextDetail (Detay Görünümü)**:
- HIDE_ON_DETAIL ise gizli
- ONLY_ON_LIST ise gizli
- ONLY_ON_FORM ise gizli
- Diğer durumlarda görünür
**ContextCreate (Oluşturma Formu)**:
- HIDE_ON_CREATE ise gizli
- ONLY_ON_UPDATE ise gizli
- ONLY_ON_LIST ise gizli
- ONLY_ON_DETAIL ise gizli
- Diğer durumlarda görünür
**ContextUpdate (Güncelleme Formu)**:
- HIDE_ON_UPDATE ise gizli
- ONLY_ON_CREATE ise gizli
- ONLY_ON_LIST ise gizli
- ONLY_ON_DETAIL ise gizli
- Diğer durumlarda görünür
**ContextPreview (Önizleme)**:
- HIDE_ON_DETAIL ise gizli
- ONLY_ON_LIST ise gizli
- ONLY_ON_FORM ise gizli
- Diğer durumlarda görünür
Örnek ¶
if field.IsVisibleInContext(ContextCreate) {
// Alanı oluşturma formunda göster
}
func (*Schema) JsonSerialize ¶
JsonSerialize, alanı JSON uyumlu bir map'e serileştirir.
Bu metod, alanın tüm özelliklerini JSON encoding için hazır bir map'e dönüştürür. Frontend'e gönderilmek üzere alanın durumunu temsil eder.
Serileştirilen Özellikler ¶
- **view**: Görünüm tipi (frontend bileşeni) - **type**: Veri tipi (ElementType) - **key**: Benzersiz tanımlayıcı - **name**: Görünen ad - **data**: Alan değeri - **props**: Ekstra özellikler - **context**: Görüntüleme bağlamı - **placeholder**: Yer tutucu metni - **label**: Etiket metni - **help_text**: Yardım metni - **read_only**: Salt okunur durumu - **disabled**: Devre dışı durumu - **required**: Zorunlu durumu - **nullable**: Boş bırakılabilir durumu - **sortable**: Sıralanabilir durumu - **filterable**: Filtrelenebilir durumu - **stacked**: Yığılmış (tam genişlik) durumu - **text_align**: Metin hizalama
Döndürür:
- JSON encoding için hazır map[string]any
Örnek:
schema := &Schema{Key: "email", Name: "E-posta", View: "email-field"}
json := schema.JsonSerialize()
// json["key"] == "email"
// json["name"] == "E-posta"
// json["view"] == "email-field"
func (*Schema) Label ¶
Label, alan için etiket metni ayarlar.
Label, alanın yanında veya üstünde gösterilen açıklayıcı metindir. Name'den farklı olarak, daha uzun ve açıklayıcı olabilir.
Parametreler ¶
- label: Etiket metni
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
Name vs Label ¶
- **Name**: Kısa, genel başlık (örn. "E-posta")
- **Label**: Daha açıklayıcı (örn. "İş E-posta Adresiniz")
Örnek ¶
field := Text("email", "E-posta").
Label("Lütfen geçerli bir e-posta adresi girin")
func (*Schema) MarkRemoveEXIFData ¶
MarkRemoveEXIFData, EXIF verilerinin kaldırılacağını belirtir.
Bu metod, yüklenen resimlerdeki EXIF metadata'sının (konum, kamera bilgisi, vb.) otomatik olarak kaldırılmasını sağlar. Gizlilik için önemlidir.
Döndürür ¶
- core.Element: Zincirleme çağrılar için Schema pointer'ı
EXIF Verileri ¶
- GPS koordinatları
- Kamera modeli
- Çekim tarihi
- Kamera ayarları
Kullanım Senaryoları ¶
- Gizlilik koruması
- Güvenlik
- Dosya boyutu azaltma
Örnek ¶
field := File("photo", "Fotoğraf").
Accept("image/jpeg", "image/png").
MarkRemoveEXIFData()
func (*Schema) Max ¶
Max, maksimum değer doğrulama kuralı ekler.
Bu metod, alanın belirtilen maksimum değerden küçük veya eşit olmasını zorunlu kılar. Sayısal alanlar için maksimum değer, string alanlar için maksimum uzunluk kontrolü yapar.
Parametreler ¶
- max: Maksimum değer (int, float64, string uzunluğu)
Döndürür ¶
- core.Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- Yaş kontrolü (max 100)
- Fiyat kontrolü (max 999999)
- Miktar kontrolü (max 1000)
- String uzunluk kontrolü
Örnek ¶
field := Number("quantity", "Miktar").Min(1).Max(1000)
func (*Schema) MaxLength ¶
MaxLength, maksimum uzunluk doğrulama kuralı ekler.
Bu metod, string alanların belirtilen maksimum karakter sayısını aşmamasını zorunlu kılar. Boşluklar da karakter olarak sayılır.
Parametreler ¶
- length: Maksimum karakter sayısı
Döndürür ¶
- core.Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- Başlık uzunluğu (max 255 karakter)
- Açıklama uzunluğu (max 1000 karakter)
- Kullanıcı adı uzunluğu (max 50 karakter)
Örnek ¶
field := Text("title", "Başlık").MaxLength(255)
func (*Schema) MaxRepeats ¶
MaxRepeats, maksimum tekrar sayısını ayarlar.
Bu metod, repeater'da en fazla kaç tane alan grubu olabileceğini belirler. Kullanıcı bu sayının üstüne çıkamaz.
Parametreler ¶
- max: Maksimum tekrar sayısı
Döndürür ¶
- core.Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- Maksimum telefon sayısı sınırı
- Maksimum adres sayısı sınırı
- Performans optimizasyonu
Örnek ¶
field := Repeater("emails", "E-posta Adresleri").
Fields(
Text("email", "E-posta").Email(),
).
MinRepeats(1).
MaxRepeats(3)
func (*Schema) MaxSize ¶
MaxSize, maksimum dosya boyutunu ayarlar.
Bu metod, yüklenebilecek dosyanın maksimum boyutunu byte cinsinden belirler. Daha büyük dosyalar reddedilir.
Parametreler ¶
- bytes: Maksimum dosya boyutu (byte cinsinden)
Döndürür ¶
- core.Element: Zincirleme çağrılar için Schema pointer'ı
Önerilen Boyutlar ¶
- Profil fotoğrafı: 2-5 MB
- Döküman: 10-50 MB
- Video: 100-500 MB
Boyut Hesaplama ¶
- 1 KB = 1024 bytes
- 1 MB = 1024 * 1024 bytes
- 1 GB = 1024 * 1024 * 1024 bytes
Örnek ¶
field := File("document", "Döküman").
Accept("application/pdf").
MaxSize(10 * 1024 * 1024) // 10MB
func (*Schema) Min ¶
Min, minimum değer doğrulama kuralı ekler.
Bu metod, alanın belirtilen minimum değerden büyük veya eşit olmasını zorunlu kılar. Sayısal alanlar için minimum değer, string alanlar için minimum uzunluk kontrolü yapar.
Parametreler ¶
- min: Minimum değer (int, float64, string uzunluğu)
Döndürür ¶
- core.Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- Yaş kontrolü (min 18)
- Fiyat kontrolü (min 0)
- Miktar kontrolü (min 1)
- String uzunluk kontrolü
Örnek ¶
field := Number("age", "Yaş").Min(18).Max(100)
func (*Schema) MinCharsForSuggestions ¶
MinCharsForSuggestions, öneri gösterimi için minimum karakter sayısı ayarlar.
Bu metod, kullanıcının kaç karakter yazdıktan sonra önerilerin gösterileceğini belirler. Performans optimizasyonu için kullanılır.
Parametreler ¶
- min: Minimum karakter sayısı
Döndürür ¶
- core.Element: Zincirleme çağrılar için Schema pointer'ı
Önerilen Değerler ¶
- 1-2: Küçük veri setleri için
- 3-4: Orta veri setleri için (önerilen)
- 5+: Büyük veri setleri için
Örnek ¶
field := Text("product", "Ürün").
WithAutoComplete("/api/products/search").
MinCharsForSuggestions(3)
func (*Schema) MinLength ¶
MinLength, minimum uzunluk doğrulama kuralı ekler.
Bu metod, string alanların belirtilen minimum karakter sayısına sahip olmasını zorunlu kılar. Boşluklar da karakter olarak sayılır.
Parametreler ¶
- length: Minimum karakter sayısı
Döndürür ¶
- core.Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- Şifre uzunluğu (min 8 karakter)
- Kullanıcı adı uzunluğu (min 3 karakter)
- Açıklama uzunluğu (min 10 karakter)
Örnek ¶
field := Password("password", "Şifre").MinLength(8).MaxLength(128)
func (*Schema) MinRepeats ¶
MinRepeats, minimum tekrar sayısını ayarlar.
Bu metod, repeater'da en az kaç tane alan grubu olması gerektiğini belirler. Kullanıcı bu sayının altına inemez.
Parametreler ¶
- min: Minimum tekrar sayısı
Döndürür ¶
- core.Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- En az bir telefon numarası zorunlu
- En az bir adres zorunlu
- Minimum varyant sayısı
Örnek ¶
field := Repeater("addresses", "Adresler").
Fields(
Text("street", "Sokak"),
Text("city", "Şehir"),
).
MinRepeats(1)
func (*Schema) Modify ¶
Modify, alan için değer modifikasyon callback'i ayarlar.
Bu metod, alanın değerinin frontend'e gönderilmeden önce değiştirilmesini sağlar. Format dönüşümü, maskeleme, hesaplama gibi işlemler için kullanılır.
Parametreler ¶
- fn: Değer modifikasyonu yapan fonksiyon
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- Tarih formatı dönüşümü
- Para birimi formatı
- Hassas veri maskeleme
- Değer hesaplama
Örnek ¶
field := Text("phone", "Telefon").Modify(func(value interface{}, c *fiber.Ctx) interface{} {
phone := value.(string)
return maskPhone(phone) // (555) ***-**-12
})
func (*Schema) Nullable ¶
Nullable, alanın boş (null) değer alabileceğini belirtir.
Nullable alanlar, veritabanında NULL değer saklayabilir. Varsayılan olarak alanlar nullable değildir.
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- Opsiyonel ilişkiler (foreign key'ler)
- Opsiyonel tarih alanları
- Opsiyonel sayısal değerler
Örnek ¶
field := BelongsTo("author", "Yazar").Nullable()
func (*Schema) OnDependencyChange ¶
func (s *Schema) OnDependencyChange(fn DependencyCallbackFunc) core.Element
OnDependencyChange, bağımlı alanlar değiştiğinde çağrılacak callback ayarlar.
Bu metod, bağımlı alanların değeri değiştiğinde özel işlemler yapılmasını sağlar. Hem oluşturma hem de güncelleme bağlamında çalışır.
Parametreler ¶
- fn: Bağımlılık değişikliği callback fonksiyonu
Döndürür ¶
- core.Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- Dinamik seçenek yükleme
- Hesaplanan değerler
- Koşullu validasyon
- Alan değeri senkronizasyonu
Örnek ¶
field := Select("city", "Şehir").
DependsOn("country").
OnDependencyChange(func(deps map[string]interface{}, ctx *fiber.Ctx) interface{} {
countryID := deps["country"]
return loadCitiesByCountry(countryID)
})
func (*Schema) OnDependencyChangeCreating ¶
func (s *Schema) OnDependencyChangeCreating(fn DependencyCallbackFunc) core.Element
OnDependencyChangeCreating, oluşturma bağlamında bağımlılık callback'i ayarlar.
Bu metod, sadece yeni kayıt oluşturulurken bağımlılık değişikliklerinde çalışır. Güncelleme işlemlerinde çalışmaz.
Parametreler ¶
- fn: Bağımlılık değişikliği callback fonksiyonu
Döndürür ¶
- core.Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- Oluşturma sırasında özel davranış
- İlk değer hesaplama
- Oluşturma bağlamına özel validasyon
Örnek ¶
field := Text("slug", "Slug").
DependsOn("title").
OnDependencyChangeCreating(func(deps map[string]interface{}, ctx *fiber.Ctx) interface{} {
return generateSlug(deps["title"].(string))
})
func (*Schema) OnDependencyChangeUpdating ¶
func (s *Schema) OnDependencyChangeUpdating(fn DependencyCallbackFunc) core.Element
OnDependencyChangeUpdating, güncelleme bağlamında bağımlılık callback'i ayarlar.
Bu metod, sadece kayıt güncellenirken bağımlılık değişikliklerinde çalışır. Oluşturma işlemlerinde çalışmaz.
Parametreler ¶
- fn: Bağımlılık değişikliği callback fonksiyonu
Döndürür ¶
- core.Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- Güncelleme sırasında özel davranış
- Değer yeniden hesaplama
- Güncelleme bağlamına özel validasyon
Örnek ¶
field := DateTime("updated_at", "Güncelleme Tarihi").
OnDependencyChangeUpdating(func(deps map[string]interface{}, ctx *fiber.Ctx) interface{} {
return time.Now()
})
func (*Schema) OnDetail ¶
OnDetail, alanı detay görünümünde gösterir.
Bu metod, alanın kayıt detay sayfasında görünür olmasını sağlar. Genellikle tüm alan bilgileri için kullanılır.
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
Örnek ¶
field := Text("description", "Açıklama").OnDetail()
func (*Schema) OnForm ¶
OnForm, alanı form görünümünde gösterir.
Bu metod, alanın hem oluşturma hem de güncelleme formlarında görünür olmasını sağlar. Kullanıcının düzenleyebileceği alanlar için kullanılır.
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
Örnek ¶
field := Text("email", "E-posta").OnForm()
func (*Schema) OnList ¶
OnList, alanı liste görünümünde gösterir.
Bu metod, alanın tablo/liste görünümünde görünür olmasını sağlar. Genellikle özet bilgiler için kullanılır.
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
Örnek ¶
field := Text("name", "İsim").OnList()
func (*Schema) OnlyOnCreate ¶
OnlyOnCreate, alanı sadece oluşturma formunda gösterir.
Bu metod, alanın yalnızca yeni kayıt oluşturma formunda görünür olmasını sağlar. Güncelleme formunda ve diğer görünümlerde gizlenir.
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- Şifre alanları (ilk oluşturmada)
- Başlangıç yapılandırma alanları
- Bir kez ayarlanan değerler
Örnek ¶
field := Password("password", "Şifre").OnlyOnCreate()
func (*Schema) OnlyOnDetail ¶
OnlyOnDetail, alanı sadece detay görünümünde gösterir.
Bu metod, alanın yalnızca kayıt detay sayfasında görünür olmasını sağlar. Liste ve formlarda gizlenir.
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- Detaylı açıklamalar
- İlişkili kayıt bilgileri
- Metadata bilgileri
Örnek ¶
field := Textarea("full_description", "Detaylı Açıklama").OnlyOnDetail()
func (*Schema) OnlyOnForm ¶
OnlyOnForm, alanı sadece formlarda gösterir.
Bu metod, alanın hem oluşturma hem de güncelleme formlarında görünür olmasını, ancak liste ve detay görünümlerinde gizlenmesini sağlar.
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- Sadece düzenleme için gerekli alanlar
- Kullanıcı girdisi gerektiren alanlar
- Görüntülenmesi gerekmeyen form alanları
Örnek ¶
field := Hidden("csrf_token", "CSRF Token").OnlyOnForm()
func (*Schema) OnlyOnList ¶
OnlyOnList, alanı sadece liste görünümünde gösterir.
Bu metod, alanın yalnızca tablo/liste görünümünde görünür olmasını sağlar. Diğer tüm görünümlerde (detail, form) gizlenir.
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- Özet bilgiler (örn. kayıt sayısı)
- Hesaplanmış değerler (örn. toplam tutar)
- Hızlı erişim linkleri
Örnek ¶
field := Text("summary", "Özet").OnlyOnList()
func (*Schema) OnlyOnUpdate ¶
OnlyOnUpdate, alanı sadece güncelleme formunda gösterir.
Bu metod, alanın yalnızca kayıt güncelleme formunda görünür olmasını sağlar. Oluşturma formunda ve diğer görünümlerde gizlenir.
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- Şifre değiştirme alanları
- Durum güncelleme alanları
- Sadece mevcut kayıtlar için geçerli alanlar
Örnek ¶
field := Password("new_password", "Yeni Şifre").OnlyOnUpdate()
func (*Schema) Options ¶
Options, alan için seçenek listesi ayarlar.
Bu metod, select, radio, checkbox gibi seçim alanları için kullanılır. Statik seçenek listesi sağlar.
Parametreler ¶
- options: Seçenek listesi (slice veya map olabilir)
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- Sabit seçenek listeleri
- Enum değerleri
- Durum seçenekleri
Örnek ¶
field := Select("status", "Durum").Options([]map[string]interface{}{
{"value": "active", "label": "Aktif"},
{"value": "inactive", "label": "Pasif"},
})
func (*Schema) Pattern ¶
Pattern, regex pattern doğrulama kuralı ekler.
Bu metod, alanın belirtilen regex pattern'ine uymasını zorunlu kılar. Özel format kontrolleri için kullanılır.
Parametreler ¶
- pattern: Regex pattern string'i
Döndürür ¶
- core.Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- Telefon numarası formatı
- Posta kodu formatı
- Özel kod formatları
- Kimlik numarası formatı
Örnek ¶
field := Text("phone", "Telefon").
Pattern(`^(\+90|0)?[0-9]{10}$`).
Placeholder("5XX XXX XX XX")
func (*Schema) Placeholder ¶
Placeholder, alan için yer tutucu metin ayarlar.
Placeholder, alan boşken gösterilen açıklayıcı metindir. Kullanıcıya ne girilmesi gerektiği hakkında ipucu verir.
Parametreler ¶
- placeholder: Yer tutucu metin
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
İyi Uygulamalar ¶
- Kısa ve açıklayıcı olmalı
- Örnek değer gösterilebilir
- Zorunlu alan açıklaması yerine kullanılmamalı
Örnek ¶
field := Text("email", "E-posta").
Placeholder("[email protected]")
func (*Schema) ReadOnly ¶
ReadOnly, alanı salt okunur olarak işaretler.
Salt okunur alanlar, kullanıcı tarafından düzenlenemez ancak görüntülenebilir. Genellikle sistem tarafından oluşturulan veya hesaplanan değerler için kullanılır.
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- Otomatik oluşturulan ID'ler
- Timestamp alanları (created_at, updated_at)
- Hesaplanan değerler
- Sistem tarafından yönetilen alanlar
Örnek ¶
field := Text("created_at", "Oluşturma Tarihi").ReadOnly()
func (*Schema) RemoveEXIFData ¶
RemoveEXIFData, dosyadan EXIF verilerini kaldırır.
Bu metod, resim dosyalarındaki EXIF metadata'sını kaldırır. Şu an için placeholder implementasyon içerir.
Parametreler ¶
- ctx: İşlem bağlamı
- file: Dosya nesnesi
Döndürür ¶
- error: İşlem hatası (nil ise başarılı)
func (*Schema) Required ¶
Required, alanı zorunlu olarak işaretler.
Zorunlu alanlar, form gönderilmeden önce doldurulmalıdır. Frontend ve backend validasyonunda kullanılır.
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
Önemli Notlar ¶
- Frontend'de otomatik validasyon eklenir
- Genellikle kırmızı yıldız (*) ile gösterilir
- Backend validasyonu ile birlikte kullanılmalıdır
Örnek ¶
field := Text("email", "E-posta").Required().Email()
func (*Schema) Resolve ¶
func (s *Schema) Resolve(fn func(value interface{}, item interface{}, c *fiber.Ctx) interface{}) Element
Resolve, alan için özel veri çıkarma callback'i ayarlar.
Bu metod, alanın resource'dan nasıl çıkarılacağını özelleştirmeye olanak tanır. İlişkili veriler, hesaplanan değerler veya özel dönüşümler için kullanılır.
Parametreler ¶
- fn: Veri çıkarma işlemini yapan fonksiyon
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- İlişkili veri çıkarma
- Hesaplanan değerler
- Format dönüşümü
- Özel veri işleme
Örnek ¶
field := Text("full_name", "Tam İsim").Resolve(func(value interface{}, item interface{}, c *fiber.Ctx) interface{} {
user := item.(*User)
return user.FirstName + " " + user.LastName
})
func (*Schema) ResolveDependencies ¶
ResolveDependencies, bağımlılık kurallarını değerlendirir.
Bu metod, verilen bağlama göre bağımlılık kurallarının karşılanıp karşılanmadığını kontrol eder. Şu an için her zaman true döner (placeholder implementasyon).
Parametreler ¶
- context: Değerlendirme bağlamı
Döndürür ¶
- bool: Bağımlılıklar karşılanıyor mu?
func (*Schema) ResolveForDisplay ¶
ResolveForDisplay, alanın değerini görüntüleme için çözümler.
Bu metod, verilen kayıttan alanın değerini çıkarır ve görüntüleme için hazırlar. Reflection kullanarak struct field'larını veya map değerlerini okur.
Parametreler ¶
- item: Değer çıkarılacak kayıt (struct veya map)
Döndürür ¶
- interface{}: Çıkarılan değer
- error: Hata durumunda hata mesajı (şu an her zaman nil)
Çalışma Mantığı ¶
1. Item nil ise, mevcut Data değerini döner 2. Item struct ise, field adına göre değer çıkarır 3. JSON tag'leri de kontrol edilir 4. Item map ise, key'e göre değer çıkarır
Örnek ¶
type User struct {
Name string `json:"name"`
}
user := &User{Name: "John"}
value, err := field.ResolveForDisplay(user)
// value == "John"
func (*Schema) ResolveHandle ¶
ResolveHandle, client-side bileşen etkileşimi için handle ayarlar.
Bu metod, frontend bileşeninin özel işlemler için kullanacağı bir handle belirler. Genellikle özel bileşenler veya dinamik davranışlar için kullanılır.
Parametreler ¶
- handle: Resolve handle string'i
Döndürür ¶
- core.Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- Özel bileşen etkileşimi
- Dinamik veri yükleme
- Client-side işlem tetikleme
Örnek ¶
field := Custom("map", "Harita").ResolveHandle("map-component")
func (*Schema) Rows ¶
Rows, textarea field'ı için satır sayısını ayarlar.
Bu metod, textarea field'larında görüntülenecek satır sayısını belirler. Satır sayısı bilgisi Props'a "rows" key'i ile kaydedilir.
Parametreler:
- rows: Satır sayısı
Döndürür:
- Element pointer'ı (method chaining için)
Örnek:
field := fields.Textarea("Description", "description").Rows(5)
func (*Schema) Searchable ¶
Searchable, alanın global aramada kullanılacağını belirtir.
Searchable alanlar, genel arama kutusunda aranabilir. Kullanıcı arama yaptığında, bu alanların içeriği taranır.
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- İsim alanları
- E-posta alanları
- Açıklama alanları
- Başlık alanları
Önemli Notlar ¶
- Performans için dikkatli kullanılmalı
- Çok fazla alan searchable yapılmamalı
- Genellikle text alanları için uygundur
Örnek ¶
field := Text("name", "İsim").Searchable()
func (*Schema) SetContext ¶
func (s *Schema) SetContext(context ElementContext) Element
SetContext, alanın görüntüleneceği bağlamı ayarlar.
Context, alanın hangi sayfalarda (list, detail, form) görüneceğini belirler. Bu metod, görünürlük kontrolü için temel mekanizmayı sağlar.
Parametreler ¶
- context: Görüntüleme bağlamı (ElementContext enum değeri)
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
Kullanılabilir Context Değerleri ¶
- SHOW_ON_LIST: Liste görünümünde göster
- SHOW_ON_DETAIL: Detay görünümünde göster
- SHOW_ON_FORM: Form görünümünde göster
- HIDE_ON_LIST: Liste görünümünde gizle
- HIDE_ON_DETAIL: Detay görünümünde gizle
- HIDE_ON_CREATE: Oluşturma formunda gizle
- HIDE_ON_UPDATE: Güncelleme formunda gizle
- ONLY_ON_LIST: Sadece liste görünümünde göster
- ONLY_ON_DETAIL: Sadece detay görünümünde göster
- ONLY_ON_CREATE: Sadece oluşturma formunda göster
- ONLY_ON_UPDATE: Sadece güncelleme formunda göster
- ONLY_ON_FORM: Sadece formlarda göster
Örnek ¶
field := &Schema{Key: "id"}
field.SetContext(HIDE_ON_FORM)
func (*Schema) SetContextForI18n ¶
SetContextForI18n, i18n çevirileri için fiber context'ini ayarlar.
func (*Schema) SetDependencies ¶
SetDependencies, alan bağımlılıklarını ayarlar.
Bu metod, alanın bağımlı olduğu diğer alanları belirler.
Parametreler ¶
- deps: Bağımlı alan adları listesi
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
Örnek ¶
field.SetDependencies([]string{"country", "state"})
func (*Schema) SetKey ¶
SetKey, alanın benzersiz tanımlayıcısını ayarlar.
Key, alanı resource model'indeki bir field'a eşlemek için kullanılır. Genellikle veritabanı sütun adı veya struct field adı ile eşleşir.
Parametreler ¶
- key: Alanın benzersiz tanımlayıcısı (örn. "email", "user_name", "created_at")
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
Önemli Notlar ¶
- Key, snake_case formatında olmalıdır
- Key, resource model'deki field adı ile eşleşmelidir
- Key değiştirildiğinde, veri çıkarma işlemi etkilenir
Örnek ¶
field := &Schema{}
field.SetKey("email_address")
func (*Schema) SetName ¶
SetName, alanın görünen adını ayarlar.
Bu metod, UI'da kullanıcıya gösterilecek alan adını belirler. Genellikle form etiketleri, tablo başlıkları ve detay görünümlerinde kullanılır.
Parametreler ¶
- name: Alanın görünen adı (örn. "E-posta Adresi", "Kullanıcı Adı")
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
Örnek ¶
field := &Schema{Key: "email"}
field.SetName("E-posta Adresi")
func (*Schema) SetTextAlign ¶
SetTextAlign, alan içeriğinin hizalamasını ayarlar.
Text align, alanın içeriğinin nasıl hizalanacağını belirler. Genellikle liste görünümünde kullanılır.
Parametreler ¶
- align: Hizalama değeri ("left", "center", "right", "justify")
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- Sayısal alanlar için sağa hizalama
- Başlıklar için ortaya hizalama
- Metin alanları için sola hizalama (varsayılan)
Örnek ¶
field := Number("price", "Fiyat").SetTextAlign("right")
func (*Schema) ShouldDisplayUsingLabels ¶
ShouldDisplayUsingLabels, etiket kullanarak görüntüleme yapılıp yapılmayacağını döner.
Döndürür ¶
- bool: Etiket kullanılacak mı?
Örnek ¶
if field.ShouldDisplayUsingLabels() {
// Değer yerine etiketi göster
}
func (*Schema) ShouldRemoveEXIFData ¶
ShouldRemoveEXIFData, EXIF verilerinin kaldırılıp kaldırılmayacağını döner.
Döndürür ¶
- bool: EXIF verileri kaldırılacak mı?
Örnek ¶
if field.ShouldRemoveEXIFData() {
// EXIF verilerini kaldır
}
func (*Schema) ShowCurrency ¶
ShowCurrency, money field için currency etiketinin formda gösterilip gösterilmeyeceğini ayarlar.
func (*Schema) ShowNumberControls ¶
ShowNumberControls, number input alanındaki artı/eksi butonlarının görünürlüğünü ayarlar.
Varsayılan değer true'dur (butonlar görünür). false gönderildiğinde frontend'de +/- butonları gizlenir.
Parametreler ¶
- show: true ise kontroller gösterilir, false ise gizlenir
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
Örnek ¶
fields.Number("Fiyat", "price").ShowNumberControls(false)
func (*Schema) ShowOnGrid ¶
ShowOnGrid, alanı grid görünümünde görünür hale getirir.
func (*Schema) ShowOnlyGrid ¶
ShowOnlyGrid, alanı index kapsamlarında (table/grid) gösterir, detail ve form görünümlerinde gizler.
func (*Schema) Sortable ¶
Sortable, alanın sıralanabilir olduğunu belirtir.
Sortable alanlar, liste görünümünde sıralama seçenekleri sunar. Kullanıcılar bu alana göre kayıtları artan veya azalan şekilde sıralayabilir.
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- İsim alanları
- Tarih alanları
- Sayısal alanlar
- Durum alanları
Örnek ¶
field := Text("name", "İsim").Sortable()
func (*Schema) Span ¶
Span, alanın form/detail grid içindeki kolon genişliğini ayarlar.
Span değeri 1 ile 12 arasındadır. Geçersiz değerler otomatik olarak clamp edilir:
- 1'den küçükse 1
- 12'den büyükse 12
Parametreler ¶
- span: Grid kolon genişliği (1-12)
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
Örnek ¶
fields.Text("Ad", "first_name").Span(6)
fields.Text("Soyad", "last_name").Span(6)
func (*Schema) Stacked ¶
Stacked, alanın tam genişlikte görüntüleneceğini belirtir.
Stacked alanlar, formda kendi satırını kaplar (100% genişlik). Varsayılan olarak alanlar yan yana dizilir, stacked alanlar alt alta dizilir.
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- Textarea alanları
- Uzun text alanları
- Önemli alanlar
- Görsel vurgu gerektiren alanlar
Örnek ¶
field := Textarea("description", "Açıklama").Stacked()
func (*Schema) Store ¶
Store, dosya depolama ayarlarını belirler.
Bu metod, yüklenen dosyaların nerede saklanacağını belirler. Disk ve path bilgilerini ayarlar.
Parametreler ¶
- disk: Depolama disk adı (örn. "local", "s3", "gcs")
- path: Depolama yolu (örn. "uploads/avatars", "documents")
Döndürür ¶
- core.Element: Zincirleme çağrılar için Schema pointer'ı
Disk Tipleri ¶
- **local**: Yerel dosya sistemi
- **s3**: Amazon S3
- **gcs**: Google Cloud Storage
- **azure**: Azure Blob Storage
Kullanım Senaryoları ¶
- Yerel depolama
- Cloud depolama
- CDN entegrasyonu
Örnek ¶
field := File("avatar", "Avatar").
Store("s3", "uploads/avatars").
Accept("image/*").
MaxSize(5 * 1024 * 1024)
func (*Schema) StoreAs ¶
func (s *Schema) StoreAs(fn StorageCallbackFunc) Element
StoreAs, alan için özel depolama callback'i ayarlar.
Bu metod, alanın veritabanına nasıl kaydedileceğini özelleştirmeye olanak tanır. Veri dönüşümü, şifreleme, hash'leme gibi işlemler için kullanılır.
Parametreler ¶
- fn: Depolama işlemini yapan fonksiyon
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- Şifre hash'leme
- Veri şifreleme
- Format dönüşümü
- Hesaplanan değerler
Örnek ¶
field := Password("password", "Şifre").StoreAs(func(value interface{}, ctx *fiber.Ctx) interface{} {
return bcrypt.HashPassword(value.(string))
})
func (*Schema) Tooltip ¶
Tooltip, alana bir tooltip (bilgi balonu) ekler.
Tooltip, kullanıcıya alan hakkında ek bilgi sağlamak için kullanılır. Frontend'te label'ın yanında bir info ikonu olarak gösterilir ve üzerine gelindiğinde tooltip metni görüntülenir.
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Örneği ¶
field := Text("Kullanıcı Adı", "username").
Tooltip("Kullanıcı adınız benzersiz olmalıdır ve en az 3 karakter içermelidir")
field := Email("E-posta", "email").
Tooltip("Geçerli bir e-posta adresi giriniz").
Required()
Not ¶
Bu metod, arka planda WithProps("tooltip", text) çağrısı yapar. Tooltip özelliği frontend bileşenleri tarafından desteklenmelidir.
func (*Schema) URL ¶
URL, URL doğrulama kuralı ekler.
Bu metod, alanın geçerli bir URL içermesini zorunlu kılar. HTTP, HTTPS ve diğer protokoller desteklenir.
Döndürür ¶
- core.Element: Zincirleme çağrılar için Schema pointer'ı
Doğrulama Kuralları ¶
- Geçerli URL formatı
- Protokol içermeli (http://, https://, vb.)
- Geçerli domain formatı
Kullanım Senaryoları ¶
- Website alanları
- Sosyal medya profil linkleri
- API endpoint alanları
Örnek ¶
field := Text("website", "Website").URL()
func (*Schema) Unique ¶
Unique, benzersizlik doğrulama kuralı ekler.
Bu metod, alanın veritabanında benzersiz olmasını zorunlu kılar. Aynı değere sahip başka bir kayıt varsa hata verir.
Parametreler ¶
- table: Kontrol edilecek tablo adı
- column: Kontrol edilecek sütun adı
Döndürür ¶
- core.Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- E-posta benzersizliği
- Kullanıcı adı benzersizliği
- Slug benzersizliği
- Kod benzersizliği
Önemli Notlar ¶
- Güncelleme işlemlerinde mevcut kaydın kendisi hariç tutulur
- Performans için veritabanı indeksi önerilir
- Büyük/küçük harf duyarlılığı veritabanına bağlıdır
Örnek ¶
field := Text("email", "E-posta").
Email().
Unique("users", "email")
func (*Schema) UpdateRules ¶
func (*Schema) ValidateAttachment ¶
ValidateAttachment, dosya yükleme doğrulaması yapar.
Bu metod, dosya adı ve boyutuna göre doğrulama yapar. Şu an için placeholder implementasyon içerir.
Parametreler ¶
- filename: Dosya adı
- size: Dosya boyutu (byte)
Döndürür ¶
- error: Doğrulama hatası (nil ise geçerli)
func (*Schema) ValidateRepeats ¶
ValidateRepeats, tekrar sayısını doğrular.
Bu metod, verilen tekrar sayısının min/max sınırları içinde olup olmadığını kontrol eder. Şu an için placeholder implementasyon içerir.
Parametreler ¶
- count: Tekrar sayısı
Döndürür ¶
- error: Doğrulama hatası (nil ise geçerli)
func (*Schema) ValidateValue ¶
ValidateValue, değeri doğrulama kurallarına göre kontrol eder.
Bu metod, verilen değerin tüm doğrulama kurallarını karşılayıp karşılamadığını kontrol eder. Şu an için placeholder implementasyon içerir.
Parametreler ¶
- value: Doğrulanacak değer
Döndürür ¶
- error: Doğrulama hatası (nil ise geçerli)
func (*Schema) When ¶
When, bağımlılık kuralı ekler.
Bu metod, belirli bir alanın belirli bir değere sahip olması durumunda bu alanın nasıl davranacağını belirler.
Parametreler ¶
- field: Kontrol edilecek alan adı
- operator: Karşılaştırma operatörü ("=", "!=", ">", "<", ">=", "<=", "in", "not_in")
- value: Karşılaştırılacak değer
Döndürür ¶
- core.Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- Koşullu alan gösterimi
- Değer bazlı validasyon
- Dinamik form davranışı
Örnek ¶
field := Text("other_reason", "Diğer Sebep").
DependsOn("reason").
When("reason", "=", "other")
func (*Schema) WithAutoComplete ¶
WithAutoComplete, alan için otomatik tamamlama URL'i ayarlar.
Bu metod, önerilerin bir API endpoint'inden yüklenmesini sağlar. Callback yerine URL kullanarak server-side öneri sistemi oluşturur.
Parametreler ¶
- url: Otomatik tamamlama API endpoint'i
Döndürür ¶
- core.Element: Zincirleme çağrılar için Schema pointer'ı
API Beklentileri ¶
- GET request ile çağrılır
- Query parameter: ?q=arama_metni
- Response: JSON array [{value, label}, ...]
Kullanım Senaryoları ¶
- Büyük veri setlerinde arama
- Uzak API entegrasyonu
- Performans optimizasyonu
Örnek ¶
field := Text("city", "Şehir").
WithAutoComplete("/api/cities/search").
MinCharsForSuggestions(2)
func (*Schema) WithBadgeVariant ¶
WithBadgeVariant, badge varyantını ayarlar.
Bu metod, badge'in görsel stilini belirler. Farklı varyantlar farklı görünümler sunar.
Parametreler ¶
- variant: Badge varyantı ("solid", "outline", "subtle", "dot")
Döndürür ¶
- core.Element: Zincirleme çağrılar için Schema pointer'ı
Varyant Tipleri ¶
- **solid**: Dolu, renkli arka plan
- **outline**: Sadece kenarlık
- **subtle**: Hafif renkli arka plan
- **dot**: Nokta ile gösterim
Örnek ¶
field := Status("priority", "Öncelik").
WithStatusColors(map[string]string{
"high": "red",
"medium": "yellow",
"low": "green",
}).
WithBadgeVariant("solid")
func (*Schema) WithEditor ¶
WithEditor, editör tipini ayarlar.
Bu metod, hangi zengin metin editörünün kullanılacağını belirler. Farklı editörler farklı özellikler sunar.
Parametreler ¶
- editorType: Editör tipi ("tinymce", "quill", "ckeditor", "markdown")
Döndürür ¶
- core.Element: Zincirleme çağrılar için Schema pointer'ı
Editör Tipleri ¶
- **tinymce**: Tam özellikli WYSIWYG editör
- **quill**: Modern, hafif editör
- **ckeditor**: Güçlü, özelleştirilebilir editör
- **markdown**: Markdown formatı editörü
Örnek ¶
field := RichText("content", "İçerik").
WithEditor("tinymce").
WithLanguage("tr").
WithTheme("modern")
func (*Schema) WithLanguage ¶
WithLanguage, editör dilini ayarlar.
Bu metod, editör arayüzünün hangi dilde gösterileceğini belirler. Menüler, butonlar ve mesajlar bu dilde gösterilir.
Parametreler ¶
- language: Dil kodu ("tr", "en", "de", "fr", vb.)
Döndürür ¶
- core.Element: Zincirleme çağrılar için Schema pointer'ı
Desteklenen Diller ¶
- tr: Türkçe
- en: İngilizce
- de: Almanca
- fr: Fransızca
- es: İspanyolca
Örnek ¶
field := RichText("description", "Açıklama").
WithEditor("quill").
WithLanguage("tr")
func (*Schema) WithPivotResource ¶
WithPivotResource, pivot resource adını ayarlar.
Bu metod, pivot alanın hangi resource'a ait olduğunu belirtir. İlişki yönetimi için kullanılır.
Parametreler ¶
- resourceName: Pivot resource adı
Döndürür ¶
- core.Element: Zincirleme çağrılar için Schema pointer'ı
Örnek ¶
field := Number("quantity", "Miktar").
AsPivot().
WithPivotResource("order_products")
func (*Schema) WithProps ¶
WithProps, alana özel bir özellik ekler.
Props, alanın frontend bileşenine iletilecek ekstra özellikleri saklar. Bu metod, özel bileşen davranışları veya stil ayarları için kullanılır.
Parametreler ¶
- key: Özellik anahtarı
- value: Özellik değeri (herhangi bir tip olabilir)
Döndürür ¶
- Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- Özel bileşen yapılandırması
- Frontend'e özel veri iletimi
- UI davranış kontrolü
- Stil ve tema ayarları
Örnek ¶
field := Text("name", "İsim").
WithProps("maxLength", 100).
WithProps("autoFocus", true).
WithProps("className", "custom-input")
func (*Schema) WithStatusColors ¶
WithStatusColors, durum renk eşleştirmesi ayarlar.
Bu metod, her durum değeri için bir renk tanımlar. Liste ve detay görünümlerinde renkli badge'ler gösterilir.
Parametreler ¶
- colors: Durum-renk eşleştirme map'i
Döndürür ¶
- core.Element: Zincirleme çağrılar için Schema pointer'ı
Renk Değerleri ¶
- Hex kodları: "#FF0000", "#00FF00"
- Renk isimleri: "red", "green", "blue"
- Tailwind sınıfları: "bg-red-500", "bg-green-500"
Kullanım Senaryoları ¶
- Sipariş durumları
- Ödeme durumları
- Kullanıcı durumları
- Görev durumları
Örnek ¶
field := Status("status", "Durum").
WithStatusColors(map[string]string{
"pending": "yellow",
"approved": "green",
"rejected": "red",
"cancelled": "gray",
})
func (*Schema) WithSuggestions ¶
WithSuggestions, alan için öneri callback'i ayarlar.
Bu metod, kullanıcı yazarken gösterilecek önerileri dinamik olarak oluşturur. Callback, arama sorgusunu alır ve öneri listesi döner.
Parametreler ¶
- fn: Öneri oluşturma fonksiyonu (string -> []interface{})
Döndürür ¶
- core.Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- Otomatik tamamlama
- Arama önerileri
- Hızlı seçim listeleri
- Dinamik filtreleme
Örnek ¶
field := Text("email", "E-posta").
WithSuggestions(func(query string) []interface{} {
return searchEmails(query)
}).
MinCharsForSuggestions(3)
func (*Schema) WithTheme ¶
WithTheme, editör temasını ayarlar.
Bu metod, editörün görsel temasını belirler. Farklı temalar farklı görünümler sunar.
Parametreler ¶
- theme: Tema adı ("modern", "classic", "dark", "light")
Döndürür ¶
- core.Element: Zincirleme çağrılar için Schema pointer'ı
Yaygın Temalar ¶
- **modern**: Modern, minimal görünüm
- **classic**: Klasik, geleneksel görünüm
- **dark**: Koyu tema
- **light**: Açık tema
Örnek ¶
field := RichText("article", "Makale").
WithEditor("ckeditor").
WithTheme("dark")
func (*Schema) WithUpload ¶
WithUpload, özel dosya yükleme callback'i ayarlar.
Bu metod, dosya yükleme işlemini özelleştirmeye olanak tanır. Dosya işleme, dönüşüm, validasyon gibi işlemler için kullanılır.
Parametreler ¶
- fn: Dosya yükleme işlemini yapan fonksiyon
Döndürür ¶
- core.Element: Zincirleme çağrılar için Schema pointer'ı
Kullanım Senaryoları ¶
- Resim boyutlandırma
- Dosya dönüşümü
- Özel validasyon
- Metadata çıkarma
Örnek ¶
field := File("image", "Resim").
WithUpload(func(file interface{}, item interface{}) error {
// Resmi yeniden boyutlandır
return resizeImage(file, 800, 600)
})
type Searchable ¶
type Searchable struct {
// contains filtered or unexported fields
}
Searchable, alanların aranabilir olmasını sağlayan bir mixin'dir.
Aranabilir sütunlar ve özel arama callback'leri için yapılandırma sağlar. Bu callback'ler, özel arama mantığı uygulamak için veritabanı sorgusunu değiştirebilir.
Kullanım ¶
type TextField struct {
fields.Base
fields.Searchable
}
field := &TextField{}
field.SetSearchableColumns([]string{"name", "email"})
field.SetSearchCallback(func(db *gorm.DB, term string) *gorm.DB {
return db.Where("LOWER(name) LIKE ?", "%"+strings.ToLower(term)+"%")
})
Daha fazla örnek için docs/Fields.md dosyasına bakın.
func (*Searchable) GetSearchCallback ¶
GetSearchCallback, arama callback fonksiyonunu döndürür. Hiçbir callback ayarlanmamışsa nil döndürür.
Döndürür:
- Arama callback fonksiyonu veya ayarlanmamışsa nil
func (*Searchable) GetSearchableColumns ¶
func (s *Searchable) GetSearchableColumns() []string
GetSearchableColumns, aranabilir sütunları döndürür. Hiçbir sütun yapılandırılmamışsa boş bir dilim döndürür.
Döndürür:
- Aranabilir sütun adlarının dilimi
func (*Searchable) SetSearchCallback ¶
SetSearchCallback, özel bir arama callback fonksiyonu ayarlar.
Callback, GORM veritabanı örneğini ve arama terimini alır, ve arama sorgusu uygulanmış değiştirilmiş bir veritabanı örneği döndürmelidir.
Parametreler:
- cb: Özel arama mantığı için veritabanı sorgusunu değiştiren fonksiyon
Örnek:
field.SetSearchCallback(func(db *gorm.DB, term string) *gorm.DB {
return db.Where(
"LOWER(name) LIKE ? OR LOWER(email) LIKE ?",
"%"+strings.ToLower(term)+"%",
"%"+strings.ToLower(term)+"%",
)
})
func (*Searchable) SetSearchableColumns ¶
func (s *Searchable) SetSearchableColumns(columns []string)
SetSearchableColumns, aranabilir sütunları ayarlar. Bu sütunlar global arama işlemlerinde kullanılır.
Parametreler:
- columns: Aranabilir olması gereken sütun adlarının listesi
Örnek:
field.SetSearchableColumns([]string{"name", "email", "username"})
type Sortable ¶
type Sortable struct {
// contains filtered or unexported fields
}
Sortable, alanların sıralanabilir olmasını sağlayan bir mixin'dir.
Sıralanabilir davranış, varsayılan sıralama yönü ve özel sıralama callback'leri için yapılandırma sağlar. Bu callback'ler veritabanı sorgusunu değiştirebilir.
Kullanım ¶
type TextField struct {
fields.Base
fields.Sortable
}
field := &TextField{}
field.SetSortable(true)
field.SetSortDirection("asc")
field.SetSortCallback(func(db *gorm.DB, direction string) *gorm.DB {
return db.Order("LOWER(name) " + direction)
})
Daha fazla örnek için docs/Fields.md dosyasına bakın.
func (*Sortable) GetSortCallback ¶
GetSortCallback, sıralama callback fonksiyonunu döndürür. Hiçbir callback ayarlanmamışsa nil döndürür.
Döndürür:
- Sıralama callback fonksiyonu veya ayarlanmamışsa nil
func (*Sortable) GetSortDirection ¶
GetSortDirection, varsayılan sıralama yönünü döndürür. Hiçbir yön ayarlanmamışsa "asc" döndürür.
Döndürür:
- Sıralama yönü ("asc" veya "desc")
func (*Sortable) IsSortable ¶
IsSortable, alanın sıralanabilir olup olmadığını döndürür.
Döndürür:
- Alan sıralanabilirse true, değilse false
func (*Sortable) SetSortCallback ¶
SetSortCallback, özel bir sıralama callback fonksiyonu ayarlar.
Callback, GORM veritabanı örneğini ve sıralama yönünü alır, ve sıralama sorgusu uygulanmış değiştirilmiş bir veritabanı örneği döndürmelidir.
Parametreler:
- cb: Özel sıralama mantığı için veritabanı sorgusunu değiştiren fonksiyon
Örnek:
field.SetSortCallback(func(db *gorm.DB, direction string) *gorm.DB {
return db.Order("LOWER(name) " + direction)
})
func (*Sortable) SetSortDirection ¶
SetSortDirection, varsayılan sıralama yönünü ayarlar.
Parametreler:
- direction: Artan sıralama için "asc" veya azalan sıralama için "desc"
Örnek:
field.SetSortDirection("desc")
func (*Sortable) SetSortable ¶
SetSortable, alanın sıralanabilir olup olmadığını ayarlar.
Parametreler:
- sortable: Sıralamayı etkinleştirmek için true, devre dışı bırakmak için false
Örnek:
field.SetSortable(true)
type StorageCallbackFunc ¶
type StorageCallbackFunc = core.StorageCallbackFunc
StorageCallbackFunc, dosya depolama işlemlerini özelleştiren callback fonksiyonudur.
Bu tip, core.StorageCallbackFunc'ın bir alias'ıdır ve dosya yükleme alanlarında (Image, File, Video, Audio) depolama davranışını özelleştirmek için kullanılır.
Kullanım Örneği ¶
field.Storage(func(file interface{}) (string, error) {
// Özel depolama mantığı
return "path/to/file", nil
})
Daha fazla bilgi için pkg/core/storage.go dosyasına bakın.
type Tab ¶
type Tab struct {
// Value, tab'ın benzersiz tanımlayıcısıdır (örn: "tr", "en", "general")
Value string `json:"value"`
// Label, tab'ın görünen adıdır (örn: "Türkçe", "English", "Genel Bilgiler")
Label string `json:"label"`
// Fields, tab içinde görüntülenecek alanların listesidir
Fields []core.Element `json:"fields"`
}
Tab, bir tab'ın yapısını temsil eder.
Her tab, benzersiz bir değer (value), görünen bir etiket (label) ve içerdiği alanlardan (fields) oluşur.
Kullanım Örneği ¶
tab := Tab{
Value: "tr",
Label: "Türkçe",
Fields: []core.Element{
fields.Text("Başlık", "title_tr"),
fields.Textarea("Açıklama", "description_tr"),
},
}
type TabsField ¶
TabsField, alanları tab'lara ayırmak için bir konteyner temsil eder.
TabsField, ilgili alanları tab'lar halinde organize etmek için kullanılır. Her tab, kendi başlığı ve içeriği ile ayrı bir bölüm oluşturur.
Kullanım Senaryoları ¶
- **Çoklu Dil Desteği**: Türkçe, İngilizce, vb. tab'ları ile çeviri alanları - **Kategorize Edilmiş Formlar**: Genel Bilgiler, Adres, İletişim tab'ları - **Karmaşık Form Organizasyonu**: Uzun formları mantıksal bölümlere ayırma - **İlgili Alan Grupları**: Benzer alanları bir arada gösterme
Özellikler ¶
- **Çoklu Tab**: Birden fazla tab ekleme - **Tab Pozisyonu**: Tab'ların konumu (top, bottom, left, right) - **Tab Variant**: Tab görünümü (default, line) - **Varsayılan Tab**: Sayfa yüklendiğinde aktif olacak tab
Kullanım Örneği ¶
tabs := fields.Tabs("Ürün Bilgileri").
AddTab("tr", "Türkçe",
fields.Text("Başlık", "title_tr"),
fields.Textarea("Açıklama", "description_tr"),
).
AddTab("en", "English",
fields.Text("Title", "title_en"),
fields.Textarea("Description", "description_en"),
).
WithSide("top").
WithVariant("line").
WithDefaultTab("tr")
func Tabs ¶
Tabs, alanları tab'lara ayırmak için yeni bir tabs konteyner oluşturur.
Bu fonksiyon, ilgili alanları tab'lar halinde organize etmek için bir konteyner oluşturur. Form sayfalarında alanları mantıksal tab'lara ayırmak için kullanılır.
Parametreler ¶
- **title**: Tabs konteyner başlığı (örn. "Ürün Bilgileri", "Çeviriler")
Kullanım Örneği ¶
tabs := fields.Tabs("Ürün Bilgileri")
Döndürür:
- Yapılandırılmış TabsField pointer'ı
func (*TabsField) AddTab ¶
AddTab, tabs konteyner'a yeni bir tab ekler.
Bu metod, tab'a benzersiz bir değer (value), görünen bir etiket (label) ve içerdiği alanları (fields) ekler.
Parametreler ¶
- **value**: Tab'ın benzersiz tanımlayıcısı (örn: "tr", "en", "general") - **label**: Tab'ın görünen adı (örn: "Türkçe", "English", "Genel Bilgiler") - **fields**: Tab içinde görüntülenecek alanlar
Kullanım Örneği ¶
tabs.AddTab("tr", "Türkçe",
fields.Text("Başlık", "title_tr"),
fields.Textarea("Açıklama", "description_tr"),
)
Döndürür:
- TabsField pointer'ı (method chaining için)
func (*TabsField) GetFields ¶
GetFields, tüm tab'lardaki alanları düz bir liste olarak döndürür.
Bu metod, tabs konteyner içindeki tüm alanları toplar ve tek bir liste halinde döndürür. Backend'de alan validasyonu ve veri işleme için kullanılır.
Kullanım Örneği ¶
allFields := tabs.GetFields() // Tüm tab'lardaki field'ları içerir
Döndürür:
- Tüm tab'lardaki alanların birleştirilmiş listesi
func (*TabsField) WithDefaultTab ¶
WithDefaultTab, sayfa yüklendiğinde aktif olacak tab'ı ayarlar.
Bu metod, varsayılan olarak hangi tab'ın açık olacağını belirler. Belirtilen value, AddTab ile eklenen tab'lardan birinin value'su olmalıdır.
Parametreler ¶
- **value**: Varsayılan aktif tab'ın value'su
Kullanım Örneği ¶
tabs.WithDefaultTab("tr") // Türkçe tab'ı varsayılan olarak açık
Döndürür:
- TabsField pointer'ı (method chaining için)
func (*TabsField) WithSide ¶
WithSide, tab'ların pozisyonunu ayarlar.
Bu metod, tab'ların nerede görüntüleneceğini belirler. Geçerli değerler: "top", "bottom", "left", "right"
Parametreler ¶
- **side**: Tab pozisyonu ("top", "bottom", "left", "right")
Kullanım Örneği ¶
tabs.WithSide("top") // Tab'lar üstte
tabs.WithSide("left") // Tab'lar solda
Döndürür:
- TabsField pointer'ı (method chaining için)
func (*TabsField) WithVariant ¶
WithVariant, tab'ların görünüm stilini ayarlar.
Bu metod, tab'ların nasıl görüntüleneceğini belirler. Geçerli değerler: "default", "line"
Parametreler ¶
- **variant**: Tab görünümü ("default", "line")
Kullanım Örneği ¶
tabs.WithVariant("default") // Varsayılan tab görünümü
tabs.WithVariant("line") // Çizgi altı tab görünümü
Döndürür:
- TabsField pointer'ı (method chaining için)
type Tag ¶
type Tag struct {
// ID, etiketin benzersiz kimliğidir (primary key).
ID int `json:"id"`
// Name, etiketin adıdır.
// Veritabanında UNIQUE constraint ile korunur.
Name string `json:"name"`
}
Tag, bir etiketi temsil eden model yapısıdır.
Bu model, içerikleri kategorize etmek için kullanılan etiketleri tutar ve BelongsToMany ilişkisinin test edilmesinde kullanılır.
İlişkiler ¶
- **BelongsToMany**: Posts (bir etiket birden fazla gönderiye ait olabilir) - **MorphTo**: Taggables (polimorfik ilişki ile farklı modellere etiket eklenebilir)
JSON Serileştirme ¶
Tüm alanlar JSON olarak serileştirilebilir.
Örnek Kullanım ¶
```go var tag Tag err := db.QueryRow("SELECT id, name FROM tags WHERE id = ?", 1).
Scan(&tag.ID, &tag.Name)
```
type Taggable ¶
type Taggable struct {
// ID, taggable kaydının benzersiz kimliğidir (primary key).
ID int `json:"id"`
// TaggableID, etiketlenen kaydın ID'sidir.
// Bu, Post, Comment veya başka bir modelin ID'si olabilir.
TaggableID int `json:"taggable_id"`
// TaggableType, etiketlenen kaydın model türünü belirtir.
// Örnek değerler: "post", "comment", "user", vb.
TaggableType string `json:"taggable_type"`
// TagID, etiketin ID'sidir (foreign key).
TagID int `json:"tag_id"`
}
Taggable, polimorfik etiketleme ilişkisini temsil eden model yapısıdır.
Bu model, farklı türdeki modellere (Post, Comment, vb.) etiket eklenmesini sağlar. MorphTo (polimorfik) ilişkisinin test edilmesinde kullanılır.
Polimorfik İlişki ¶
Polimorfik ilişki, bir modelin birden fazla farklı model türü ile ilişkilendirilmesini sağlar: - Bir etiket bir Post'a eklenebilir (taggable_type = "post") - Bir etiket bir Comment'e eklenebilir (taggable_type = "comment") - Gelecekte başka model türleri de eklenebilir
Veritabanı Yapısı ¶
- taggable_id: İlişkilendirilen kaydın ID'si - taggable_type: İlişkilendirilen modelin türü (string) - tag_id: Etiketin ID'si
Avantajlar ¶
- **Esneklik**: Yeni model türleri kolayca eklenebilir - **Tekrar Kullanılabilirlik**: Aynı etiket sistemi farklı modellerde kullanılabilir - **Genişletilebilirlik**: Yeni özellikler kolayca eklenebilir
Dezavantajlar ¶
- **Foreign Key Constraint Yok**: taggable_id için doğrudan foreign key tanımlanamaz - **Tip Güvenliği**: taggable_type string olduğu için yazım hataları olabilir - **Performans**: Sorgular daha karmaşık olabilir
Önemli Notlar ¶
- taggable_type değeri tutarlı olmalıdır (örn: "post", "comment") - Silme işlemlerinde cascade dikkatli yapılmalıdır - Sorgularda hem taggable_id hem de taggable_type kullanılmalıdır
Örnek Kullanım ¶
```go // Bir gönderiye etiket ekle _, err := db.Exec(`
INSERT INTO taggables (taggable_id, taggable_type, tag_id) VALUES (?, ?, ?)
`, 1, "post", 2)
// Bir gönderinin tüm etiketlerini getir (polimorfik sorgu) rows, err := db.Query(`
SELECT t.id, t.name FROM tags t JOIN taggables tg ON t.id = tg.tag_id WHERE tg.taggable_id = ? AND tg.taggable_type = ?
`, 1, "post")
// Bir etiketin tüm gönderilerini getir rows, err := db.Query(`
SELECT p.id, p.title FROM posts p JOIN taggables tg ON p.id = tg.taggable_id WHERE tg.tag_id = ? AND tg.taggable_type = ?
`, 1, "post") ```
type TestDB ¶
type TestDB struct {
// DB, aktif SQLite veritabanı bağlantısını tutar.
// Bu bağlantı üzerinden tüm SQL işlemleri gerçekleştirilir.
DB *sql.DB
// contains filtered or unexported fields
}
TestDB, test senaryoları için veritabanı bağlantısı sağlayan ana yapıdır.
Bu yapı, SQLite in-memory veritabanı kullanarak izole test ortamları oluşturur. Her test için temiz bir veritabanı örneği sağlar ve test sonunda otomatik temizlik yapılmasını kolaylaştırır.
Özellikler ¶
- In-memory SQLite veritabanı (disk I/O yok, hızlı testler) - Otomatik tablo oluşturma - Önceden tanımlı test verileri - Test context'i ile entegrasyon
Avantajlar ¶
- **Hız**: In-memory veritabanı sayesinde çok hızlı test çalıştırma - **İzolasyon**: Her test kendi veritabanı örneğine sahip - **Temizlik**: Test sonunda otomatik temizleme - **Tutarlılık**: Her test aynı başlangıç durumu ile çalışır
Dezavantajlar ¶
- SQLite sınırlamaları (bazı SQL özellikleri desteklenmez) - Gerçek veritabanı motorlarından farklı davranışlar gösterebilir - Büyük veri setleri için bellek kullanımı artabilir
Önemli Notlar ¶
- Her test için yeni bir TestDB örneği oluşturun - Test sonunda mutlaka Close() metodunu çağırın (defer kullanın) - In-memory veritabanı, bağlantı kapandığında tüm verileri kaybeder
Örnek Kullanım ¶
```go
func TestUserQueries(t *testing.T) {
testDB := NewTestDB(t)
defer testDB.Close()
// Test kodunuz
rows, err := testDB.DB.Query("SELECT * FROM users WHERE id = ?", 1)
if err != nil {
t.Fatal(err)
}
defer rows.Close()
}
```
func NewTestDB ¶
NewTestDB, yeni bir test veritabanı oluşturur ve başlatır.
Bu fonksiyon, SQLite in-memory veritabanı kullanarak tamamen izole bir test ortamı sağlar. Veritabanı otomatik olarak tüm gerekli tabloları oluşturur ve test verileri ile doldurur.
İşlem Adımları ¶
1. In-memory SQLite veritabanı bağlantısı açar 2. Tüm test tablolarını oluşturur (users, posts, comments, tags, profiles, vb.) 3. Örnek test verilerini ekler 4. Hazır TestDB örneğini döndürür
Parametreler ¶
- `t`: Test context'i. Hata durumlarında test başarısızlığını bildirmek için kullanılır.
Dönüş Değeri ¶
Kullanıma hazır TestDB örneği döndürür. Bu örnek üzerinden tüm veritabanı işlemleri yapılabilir.
Hata Yönetimi ¶
Herhangi bir hata durumunda (veritabanı açılamaz, tablolar oluşturulamaz, veri eklenemez) test otomatik olarak başarısız sayılır (t.Fatalf kullanılır).
Önemli Notlar ¶
- **Bellek Kullanımı**: In-memory veritabanı RAM'de çalışır, disk I/O yoktur - **İzolasyon**: Her çağrı tamamen bağımsız bir veritabanı oluşturur - **Temizlik**: Mutlaka defer ile Close() çağrılmalıdır - **Performans**: Disk tabanlı veritabanlarından çok daha hızlıdır
Kullanım Örnekleri ¶
```go // Temel kullanım
func TestBasicQuery(t *testing.T) {
testDB := NewTestDB(t)
defer testDB.Close()
var count int
err := testDB.DB.QueryRow("SELECT COUNT(*) FROM users").Scan(&count)
if err != nil {
t.Fatal(err)
}
if count != 3 {
t.Errorf("Expected 3 users, got %d", count)
}
}
// İlişkisel sorgu testi
func TestRelationships(t *testing.T) {
testDB := NewTestDB(t)
defer testDB.Close()
// User'ın post'larını getir
rows, err := testDB.DB.Query(`
SELECT p.title FROM posts p
JOIN users u ON p.user_id = u.id
WHERE u.email = ?
`, "[email protected]")
if err != nil {
t.Fatal(err)
}
defer rows.Close()
}
```
Test Verileri ¶
Fonksiyon aşağıdaki örnek verileri otomatik olarak oluşturur: - 3 kullanıcı (John Doe, Jane Smith, Bob Johnson) - 3 gönderi (farklı kullanıcılara ait) - 3 yorum - 4 etiket (golang, database, testing, api) - 2 profil - Çeşitli ilişkisel veriler (post-tag, taggables)
func (*TestDB) Close ¶
Close, test veritabanı bağlantısını kapatır ve kaynakları serbest bırakır.
Bu metod, test sonunda veritabanı bağlantısını düzgün bir şekilde kapatır. In-memory veritabanı kullanıldığı için, bağlantı kapandığında tüm veriler kaybolur.
Dönüş Değeri ¶
Bağlantı kapatma işlemi sırasında oluşan hata varsa döndürür, yoksa nil döner.
Önemli Notlar ¶
- **Mutlaka Çağrılmalı**: Her NewTestDB çağrısından sonra mutlaka Close çağrılmalıdır - **Defer Kullanımı**: En iyi pratik, defer ile kullanmaktır - **Veri Kaybı**: In-memory veritabanı olduğu için, Close sonrası tüm veriler kaybolur - **Kaynak Sızıntısı**: Close çağrılmazsa veritabanı bağlantısı açık kalır
Kullanım Örnekleri ¶
```go // Önerilen kullanım (defer ile)
func TestExample(t *testing.T) {
testDB := NewTestDB(t)
defer testDB.Close() // Test bitince otomatik kapanır
// Test kodunuz...
}
// Manuel kullanım (önerilmez)
func TestManual(t *testing.T) {
testDB := NewTestDB(t)
// Test kodunuz...
if err := testDB.Close(); err != nil {
t.Errorf("Failed to close database: %v", err)
}
}
```
type User ¶
type User struct {
// ID, kullanıcının benzersiz kimliğidir (primary key).
ID int `json:"id"`
// Name, kullanıcının tam adıdır.
Name string `json:"name"`
// Email, kullanıcının benzersiz e-posta adresidir.
// Veritabanında UNIQUE constraint ile korunur.
Email string `json:"email"`
}
User, bir kullanıcıyı temsil eden model yapısıdır.
Bu model, sistemdeki kullanıcı bilgilerini tutar ve diğer modeller ile ilişkilendirilir. HasOne ve HasMany ilişkilerinin test edilmesinde kullanılır.
İlişkiler ¶
- **HasOne**: Profile (bir kullanıcının bir profili vardır) - **HasMany**: Posts (bir kullanıcının birden fazla gönderisi olabilir) - **HasMany**: Comments (bir kullanıcının birden fazla yorumu olabilir)
JSON Serileştirme ¶
Tüm alanlar JSON olarak serileştirilebilir. API yanıtlarında kullanılabilir.
Örnek Kullanım ¶
```go var user User err := db.QueryRow("SELECT id, name, email FROM users WHERE id = ?", 1).
Scan(&user.ID, &user.Name, &user.Email)
```
type Validatable ¶
type Validatable struct {
// contains filtered or unexported fields
}
Validatable, alanların doğrulama kurallarına sahip olmasını sağlayan bir mixin'dir.
String tabanlı doğrulama kuralları ve karmaşık doğrulama mantığı uygulayabilen özel doğrulayıcı fonksiyonları için yapılandırma sağlar.
Kullanım ¶
type EmailField struct {
fields.Base
fields.Validatable
}
field := &EmailField{}
field.SetRules([]string{"required", "email"})
field.AddValidator(func(value any) error {
email, ok := value.(string)
if !ok {
return fmt.Errorf("email bir string olmalıdır")
}
if !strings.Contains(email, "@") {
return fmt.Errorf("geçersiz email formatı")
}
return nil
})
Daha fazla örnek için docs/Fields.md dosyasına bakın.
func (*Validatable) AddValidator ¶
func (v *Validatable) AddValidator(validator func(any) error)
AddValidator, özel bir doğrulayıcı fonksiyonu ekler.
Doğrulayıcı, alan değerini alır ve doğrulama başarısız olursa bir hata, doğrulama başarılı olursa nil döndürmelidir.
Parametreler:
- validator: Alan değerini doğrulayan fonksiyon
Örnek:
field.AddValidator(func(value any) error {
str, ok := value.(string)
if !ok {
return fmt.Errorf("değer bir string olmalıdır")
}
if len(str) < 8 {
return fmt.Errorf("değer en az 8 karakter olmalıdır")
}
return nil
})
func (*Validatable) GetRules ¶
func (v *Validatable) GetRules() []string
GetRules, doğrulama kurallarını döndürür. Hiçbir kural yapılandırılmamışsa boş bir dilim döndürür.
Döndürür:
- Doğrulama kuralı tanımlayıcılarının dilimi
func (*Validatable) GetValidators ¶
func (v *Validatable) GetValidators() []func(any) error
GetValidators, özel doğrulayıcı fonksiyonlarını döndürür. Hiçbir doğrulayıcı eklenmemişse boş bir dilim döndürür.
Döndürür:
- Doğrulayıcı fonksiyonlarının dilimi
func (*Validatable) SetRules ¶
func (v *Validatable) SetRules(rules []string)
SetRules, alan için doğrulama kurallarını ayarlar.
Kurallar, yerleşik doğrulayıcılara karşılık gelen string tabanlı tanımlayıcılardır (örn. "required", "email", "min:8", "max:255").
Parametreler:
- rules: Doğrulama kuralı tanımlayıcılarının listesi
Örnek:
field.SetRules([]string{"required", "email", "max:255"})
type ValidationResult ¶
type ValidationResult struct {
IsValid bool // Doğrulama başarılı mı?
Errors map[string][]string // Alan adı -> hata mesajları
}
ValidationResult, doğrulama sonucunu temsil eder.
Bu yapı, doğrulama işleminin başarılı olup olmadığını ve varsa hata mesajlarını içerir.
Kullanım Örneği ¶
result := ValidationResult{
IsValid: false,
Errors: map[string][]string{
"email": {"Geçerli bir e-posta adresi giriniz"},
},
}
type ValidationRule ¶
type ValidationRule struct {
Name string // Kural adı (required, email, min, vb.)
Parameters []interface{} // Kural parametreleri
Message string // Hata mesajı
}
ValidationRule, bir alan için doğrulama kuralını temsil eder.
Doğrulama kuralları, form verilerinin belirli kriterlere uygun olup olmadığını kontrol eder. Her kural bir ad, parametreler ve hata mesajı içerir.
Kullanım Örneği ¶
rule := fields.Required() rule := fields.MinLength(5) rule := fields.EmailRule()
Daha fazla bilgi için docs/Fields.md dosyasına bakın.
func EmailRule ¶
func EmailRule() ValidationRule
EmailRule, e-posta formatı için doğrulama kuralı döndürür.
Bu kural, alanın geçerli bir e-posta adresi formatında olmasını zorunlu kılar. RFC 5322 standardına uygun e-posta adresleri kabul edilir.
Kullanım Örneği ¶
field.Rules(fields.EmailRule()) // Geçerli e-posta formatı: [email protected]
Döndürür:
- ValidationRule: "This field must be a valid email address" hata mesajı ile
func Exists ¶
func Exists(table, column string) ValidationRule
Exists, veritabanı varlığı için doğrulama kuralı döndürür.
Bu kural, alanın veritabanında mevcut olmasını zorunlu kılar. Belirtilen değere sahip bir kayıt yoksa doğrulama başarısız olur.
Parametreler ¶
- **table**: Tablo adı - **column**: Sütun adı
Kullanım Örneği ¶
field.Rules(fields.Exists("categories", "id"))
// Kategori ID'si categories tablosunda mevcut olmalıdır
Döndürür:
- ValidationRule: "This value does not exist" hata mesajı ile
func Max ¶
func Max(max interface{}) ValidationRule
Max, maksimum değer için doğrulama kuralı döndürür.
Bu kural, sayısal alanların belirtilen maksimum değerden küçük veya eşit olmasını zorunlu kılar.
Parametreler ¶
- **max**: Maksimum değer (int, float, vb.)
Kullanım Örneği ¶
field.Rules(fields.Max(100)) // Değer en fazla 100 olmalıdır
Döndürür:
- ValidationRule: "This field must be at most {max}" hata mesajı ile
func MaxLength ¶
func MaxLength(length int) ValidationRule
MaxLength, maksimum string uzunluğu için doğrulama kuralı döndürür.
Bu kural, string alanların belirtilen maksimum karakter sayısından kısa veya eşit olmasını zorunlu kılar.
Parametreler ¶
- **length**: Maksimum karakter sayısı
Kullanım Örneği ¶
field.Rules(fields.MaxLength(255)) // String en fazla 255 karakter olmalıdır
Döndürür:
- ValidationRule: "This field must be at most {length} characters" hata mesajı ile
func MergeValidationRules ¶
func MergeValidationRules(base, extra []ValidationRule) []ValidationRule
func Min ¶
func Min(min interface{}) ValidationRule
Min, minimum değer için doğrulama kuralı döndürür.
Bu kural, sayısal alanların belirtilen minimum değerden büyük veya eşit olmasını zorunlu kılar.
Parametreler ¶
- **min**: Minimum değer (int, float, vb.)
Kullanım Örneği ¶
field.Rules(fields.Min(18)) // Değer en az 18 olmalıdır
Döndürür:
- ValidationRule: "This field must be at least {min}" hata mesajı ile
func MinLength ¶
func MinLength(length int) ValidationRule
MinLength, minimum string uzunluğu için doğrulama kuralı döndürür.
Bu kural, string alanların belirtilen minimum karakter sayısından uzun veya eşit olmasını zorunlu kılar.
Parametreler ¶
- **length**: Minimum karakter sayısı
Kullanım Örneği ¶
field.Rules(fields.MinLength(5)) // String en az 5 karakter olmalıdır
Döndürür:
- ValidationRule: "This field must be at least {length} characters" hata mesajı ile
func Pattern ¶
func Pattern(pattern string) ValidationRule
Pattern, regex pattern eşleştirme için doğrulama kuralı döndürür.
Bu kural, alanın belirtilen regex pattern'ine uygun olmasını zorunlu kılar.
Parametreler ¶
- **pattern**: Regex pattern (örn. "^[A-Z][a-z]+$")
Kullanım Örneği ¶
field.Rules(fields.Pattern("^[0-9]{5}$"))
// 5 haneli sayı formatı (örn. 12345)
Döndürür:
- ValidationRule: "This field format is invalid" hata mesajı ile
func Required ¶
func Required() ValidationRule
Required, zorunlu alanlar için doğrulama kuralı döndürür.
Bu kural, alanın boş olmamasını zorunlu kılar. Boş string, nil, boş slice gibi değerler geçersiz sayılır.
Kullanım Örneği ¶
field.Rules(fields.Required()) // Alan boş bırakılamaz
Döndürür:
- ValidationRule: "This field is required" hata mesajı ile
func URL ¶
func URL() ValidationRule
URL, URL formatı için doğrulama kuralı döndürür.
Bu kural, alanın geçerli bir URL formatında olmasını zorunlu kılar. HTTP, HTTPS gibi protokoller desteklenir.
Kullanım Örneği ¶
field.Rules(fields.URL()) // Geçerli URL formatı: https://example.com
Döndürür:
- ValidationRule: "This field must be a valid URL" hata mesajı ile
func Unique ¶
func Unique(table, column string) ValidationRule
Unique, veritabanı benzersizliği için doğrulama kuralı döndürür.
Bu kural, alanın veritabanında benzersiz olmasını zorunlu kılar. Aynı değere sahip başka bir kayıt varsa doğrulama başarısız olur.
Parametreler ¶
- **table**: Tablo adı - **column**: Sütun adı
Kullanım Örneği ¶
field.Rules(fields.Unique("users", "email"))
// E-posta adresi users tablosunda benzersiz olmalıdır
Döndürür:
- ValidationRule: "This value already exists" hata mesajı ile
type ValidatorFunc ¶
type ValidatorFunc func(value interface{}, context interface{}) error
ValidatorFunc, bir değeri doğrulayan fonksiyondur.
Bu tip, özel doğrulama mantığı tanımlamak için kullanılır. Fonksiyon, değer geçerliyse nil, geçersizse hata döndürür.
Kullanım Örneği ¶
validator := func(value interface{}, context interface{}) error {
if value == nil {
return fmt.Errorf("değer boş olamaz")
}
return nil
}
func GetCustomValidator ¶
func GetCustomValidator(name string) (ValidatorFunc, bool)
GetCustomValidator retrieves a global custom validator
type VisibilityContext ¶
type VisibilityContext = core.VisibilityContext
VisibilityContext, görünürlük kontrolü için bağlam bilgisini sağlar.
Bu tip, core.VisibilityContext'in bir alias'ıdır ve elemanların hangi işlem sırasında (oluşturma, güncelleme, listeleme, vb.) görüntüleneceğini belirler.
Daha fazla bilgi için pkg/core/visibility_context.go dosyasına bakın.
const ( ContextIndex VisibilityContext = core.ContextIndex ContextGrid VisibilityContext = core.ContextGrid ContextDetail VisibilityContext = core.ContextDetail ContextCreate VisibilityContext = core.ContextCreate ContextUpdate VisibilityContext = core.ContextUpdate ContextPreview VisibilityContext = core.ContextPreview )
type VisibilityFunc ¶
type VisibilityFunc = core.VisibilityFunc
VisibilityFunc, bir elemanın görünürlüğünü kontrol eden callback fonksiyonudur.
Bu tip, core.VisibilityFunc'ın bir alias'ıdır ve elemanların dinamik olarak gösterilip gizlenmesini sağlar.
Kullanım Örneği ¶
field.ShowIf(func(ctx VisibilityContext) bool {
return ctx == ContextCreate
})
Daha fazla bilgi için pkg/core/visibility.go dosyasına bakın.
Source Files
¶
- base.go
- belongs_to.go
- belongs_to_many.go
- contract.go
- currency.go
- dependency.go
- dependency_resolver.go
- dialog.go
- enum.go
- fields.go
- gorm_config.go
- has_many.go
- has_one.go
- mixins.go
- morph_to.go
- morph_to_many.go
- panel.go
- relationship.go
- relationship_constraints.go
- relationship_counting.go
- relationship_display.go
- relationship_existence.go
- relationship_filter.go
- relationship_gorm_config.go
- relationship_hover_card.go
- relationship_loader.go
- relationship_pagination.go
- relationship_query.go
- relationship_search.go
- relationship_serialization.go
- relationship_sort.go
- relationship_title_fallback.go
- relationship_validator.go
- tabs.go
- test_helpers.go
- validation.go