### Implementing Authentication in Go Source: https://context7.com/qor/admin/llms.txt Provides an example of implementing the Auth interface to integrate custom authentication and authorization into the QOR admin panel. This involves defining methods for getting the current user, and providing login and logout URLs. ```go // Auth interface type Auth interface { GetCurrentUser(*Context) qor.CurrentUser LoginURL(*Context) string LogoutURL(*Context) string } // Custom auth implementation type AdminAuth struct{} func (auth AdminAuth) GetCurrentUser(context *admin.Context) qor.CurrentUser { // Get user from session session := context.Request.Context().Value("session").(*Session) if session == nil || session.UserID == 0 { return nil } var user User if err := context.GetDB().First(&user, session.UserID).Error; err != nil { return nil } return &user } func (auth AdminAuth) LoginURL(context *admin.Context) string { return "/admin/login" } func (auth AdminAuth) LogoutURL(context *admin.Context) string { return "/admin/logout" } // User must implement qor.CurrentUser interface type User struct { gorm.Model Email string Role string } func (u *User) DisplayName() string { return u.Email } // Set auth on admin Admin.SetAuth(AdminAuth{}) ``` -------------------------------- ### Implement AssignVersionName for Versioned Structs (Go) Source: https://github.com/qor/admin/blob/master/README.md Provides an example of implementing the 'AssignVersionName' method on a versioned struct (e.g., 'Factory'). This method is required to assign a unique version name to an object when creating a new version, ensuring proper version management. ```go func (fac *Factory) AssignVersionName(db *gorm.DB) { var count int name := time.Now().Format("2006-01-02") if err := db.Model(&CollectionWithVersion{}).Where("id = ? AND version_name like ?", fac.ID, name+"%" ).Count(&count).Error; err != nil { panic(err) } fac.VersionName = fmt.Sprintf("%s-v%v", name, count+1) } ``` -------------------------------- ### Initialize QOR Admin Interface Source: https://github.com/qor/admin/blob/master/README.md Demonstrates how to set up a basic QOR Admin instance, register GORM models, and mount the interface to an HTTP server. ```go package main import ( "fmt" "net/http" "github.com/jinzhu/gorm" _ "github.com/mattn/go-sqlite3" "github.com/qor/admin" ) type User struct { gorm.Model Name string } type Product struct { gorm.Model Name string Description string } func main() { DB, _ := gorm.Open("sqlite3", "demo.db") DB.AutoMigrate(&User{}, &Product{}) Admin := admin.New(&admin.AdminConfig{DB: DB}) Admin.AddResource(&User{}) Admin.AddResource(&Product{}) mux := http.NewServeMux() Admin.MountTo("/admin", mux) fmt.Println("Listening on: 9000") http.ListenAndServe(":9000", mux) } ``` -------------------------------- ### Initialize QOR Admin Instance Source: https://context7.com/qor/admin/llms.txt Demonstrates how to initialize the Admin struct with a database connection, register GORM models as resources, and mount the interface to an HTTP server. ```go package main import ( "fmt" "net/http" "github.com/jinzhu/gorm" _ "github.com/mattn/go-sqlite3" "github.com/qor/admin" ) type User struct { gorm.Model Name string Email string } type Product struct { gorm.Model Name string Description string `gorm:"type:text"` Price float64 } func main() { DB, _ := gorm.Open("sqlite3", "demo.db") DB.AutoMigrate(&User{}, &Product{}) // Create admin with database configuration Admin := admin.New(&admin.AdminConfig{ DB: DB, SiteName: "My Admin Panel", }) // Add resources to admin Admin.AddResource(&User{}) Admin.AddResource(&Product{}) // Mount admin to HTTP server mux := http.NewServeMux() Admin.MountTo("/admin", mux) fmt.Println("Admin running at http://localhost:9000/admin") http.ListenAndServe(":9000", mux) } ``` -------------------------------- ### Register and Configure Admin Resources Source: https://context7.com/qor/admin/llms.txt Shows how to register database models with custom configurations such as menu hierarchy, icons, permissions, and singleton status. ```go // Add resource with custom configuration userResource := Admin.AddResource(&User{}, &admin.Config{ Name: "Members", IconName: "person", Menu: []string{"User Management"}, Priority: 1, PageCount: 25, }) // Add singleton resource (single record, e.g., site settings) Admin.AddResource(&SiteSettings{}, &admin.Config{ Name: "Site Settings", Singleton: true, }) // Get existing resource by name res := Admin.GetResource("Members") // Get all registered resources resources := Admin.GetResources() ``` -------------------------------- ### Querying Data with Searcher and Pagination Source: https://context7.com/qor/admin/llms.txt Demonstrates how to configure default pagination settings and use the Searcher API to perform programmatic data queries, apply scopes, and retrieve pagination metadata. ```go admin.PaginationPageCount = 25 productResource := Admin.AddResource(&Product{}, &admin.Config{ PageCount: 50, }) func customHandler(context *admin.Context) { searcher := &admin.Searcher{Context: context} searcher.Page(1).PerPage(10) searcher = searcher.Scope("Published") results, err := searcher.FindMany() result, err := searcher.FindOne() pagination := searcher.Pagination fmt.Printf("Total: %d, Pages: %d, Current: %d\n", pagination.Total, pagination.Pages, pagination.CurrentPage, ) } ``` -------------------------------- ### Configuring Global Search Resources Source: https://context7.com/qor/admin/llms.txt Shows how to register models into the global search center and define searchable attributes to enable cross-model search functionality. ```go Admin.AddSearchResource( Admin.GetResource("Product"), Admin.GetResource("User"), Admin.GetResource("Order"), ) productResource.SearchAttrs("Name", "Description", "SKU") userResource.SearchAttrs("Name", "Email") orderResource.SearchAttrs("ID", "User.Name", "User.Email") ``` -------------------------------- ### Applying and Managing Themes for Resources in Go Source: https://context7.com/qor/admin/llms.txt Allows customization of the visual appearance and behavior of QOR Admin resources by applying themes. It supports using built-in themes, creating custom themes by implementing the `ThemeInterface`, and retrieving the currently applied theme from a resource. Custom themes require defining their name, view paths, and configuration logic. ```go package main import ( "github.com/qor/admin" ) // Theme interface type ThemeInterface interface { GetName() string GetViewPaths() []string ConfigAdminTheme(*Resource) } // Use built-in theme productResource.UseTheme("slideout") // Create custom theme type DarkTheme struct { admin.Theme } func (t DarkTheme) GetName() string { return "dark" } func (t DarkTheme) GetViewPaths() []string { return []string{"themes/dark/views"} } func (t DarkTheme) ConfigAdminTheme(res *admin.Resource) { // Configure resource for dark theme } // Apply custom theme productResource.UseTheme(&DarkTheme{}) // Get theme from resource theme := productResource.GetTheme("dark") ``` -------------------------------- ### Defining Data Scopes for Filtering Source: https://context7.com/qor/admin/llms.txt Demonstrates how to create reusable database filters (scopes) for index pages. Scopes can be grouped, set as defaults, or restricted based on user context. ```go type Scope struct { Name string Label string Group string Visible func(context *Context) bool Handler func(*gorm.DB, *qor.Context) *gorm.DB Default bool } productResource.Scope(&admin.Scope{ Name: "Published", Label: "Published Products", Handler: func(db *gorm.DB, context *qor.Context) *gorm.DB { return db.Where("status = ?", "published") }, }) ``` -------------------------------- ### Managing Context for Rendering and Responses Source: https://context7.com/qor/admin/llms.txt Explains the use of admin.Context methods to handle template rendering, JSON responses, flash messages, and resource URL generation within custom handlers. ```go func customHandler(context *admin.Context) { context.Execute("custom_template", data) html := context.Render("partial_name", data) context.JSON("show", map[string]interface{}{ "status": "success", "data": result, }) context.Flash("Operation successful", "success") context.Set("key", "value") user := context.CurrentUser url := context.URLFor(product, productResource) } ``` -------------------------------- ### Print All Registered Routes (Go) Source: https://github.com/qor/admin/blob/master/README.md Demonstrates how to print all registered routes within a QOR admin instance. This utility function is helpful for debugging and understanding the routing configuration of the admin interface. ```go // adm is a QOR admin instance adm.GetRouter().PrintRoutes() ``` -------------------------------- ### Configure Resource Attributes and Views Source: https://context7.com/qor/admin/llms.txt Configures which attributes are displayed on index, new, edit, and show pages, including support for sections, sorting, and search functionality. ```go // Set attributes for index page (list view) productResource.IndexAttrs("ID", "Name", "Price", "CreatedAt") // Exclude specific attributes with minus prefix productResource.IndexAttrs("-Description", "-UpdatedAt") // Set attributes for new record form productResource.NewAttrs("Name", "Description", "Price", "Category") // Set attributes for edit form with sections productResource.EditAttrs( &admin.Section{ Title: "Basic Information", Rows: [][]string{ {"Name"}, {"Code", "Price"}, }, }, &admin.Section{ Title: "Details", Rows: [][]string{ {"Category", "Brand"}, {"Description"}, }, }, ) // Set attributes for show page productResource.ShowAttrs("Name", "Description", "Price", "Category", "CreatedAt") // Set sortable columns for index page productResource.SortableAttrs("Name", "Price", "CreatedAt") // Set searchable attributes productResource.SearchAttrs("Name", "Code", "Category.Name", "Brand.Name") ``` -------------------------------- ### Configure Factory Resource with Manager SelectOne (Go) Source: https://github.com/qor/admin/blob/master/README.md Configures the 'Manager' meta within the 'Factory' resource to use a 'SelectOne' input type. It utilizes the previously generated 'managerSelector' to provide a dropdown for selecting a related Manager, supporting composite primary keys. ```go managerSelector := generateRemoteManagerSelector(adm) factoryRes.Meta(&admin.Meta{ Name: "Manager", Config: &admin.SelectOneConfig{ RemoteDataResource: managerSelector, }, }) ``` -------------------------------- ### Adding Sidebar Menus in Go Source: https://context7.com/qor/admin/llms.txt Demonstrates how to customize the admin sidebar by adding main menus, submenus, and external links. The Menu struct allows for defining name, icon, link, priority, and permissions for each menu item. ```go // Menu struct definition type Menu struct { Name string IconName string Link string RelativePath string Priority int // Higher = appears first, negative = appears last Ancestors []string Permissioner HasPermissioner Permission *roles.Permission } // Add custom menu with external link Admin.AddMenu(&admin.Menu{ Name: "Dashboard", IconName: "dashboard", Link: "/admin", Priority: 100, }) // Add menu with submenu hierarchy Admin.AddMenu(&admin.Menu{ Name: "Products", Ancestors: []string{"Store"}, IconName: "shopping_cart", Priority: 10, }) Admin.AddMenu(&admin.Menu{ Name: "Orders", Ancestors: []string{"Store"}, IconName: "receipt", Priority: 9, }) // Add external link menu Admin.AddMenu(&admin.Menu{ Name: "View Site", Link: "/", IconName: "open_in_new", Priority: -1, // Appears at bottom }) // Get menu and submenus storeMenu := Admin.GetMenu("Store") subMenus := storeMenu.GetSubMenus() ``` -------------------------------- ### Configure Select One Fields in Go Source: https://context7.com/qor/admin/llms.txt Shows how to configure 'select_one' meta fields in QOR Admin for single-choice selections. This includes using static string arrays, key-value pairs, dynamic collections fetched from a database, and remote data resources for asynchronous loading. ```go // SelectOneConfig for single selection fields productResource.Meta(&admin.Meta{ Name: "Category", Config: &admin.SelectOneConfig{ Collection: []string{"Electronics", "Clothing", "Books", "Home"}, Placeholder: "Select a category", AllowBlank: true, }, }) // SelectOneConfig with key-value pairs productResource.Meta(&admin.Meta{ Name: "Status", Config: &admin.SelectOneConfig{ Collection: [][]string{ {"draft", "Draft"}, {"published", "Published"}, {"archived", "Archived"}, }, }, }) // SelectOneConfig with dynamic collection productResource.Meta(&admin.Meta{ Name: "Author", Config: &admin.SelectOneConfig{ Collection: func(record interface{}, context *qor.Context) [][]string { var authors []Author context.GetDB().Find(&authors) var results [][]string for _, author := range authors { results = append(results, []string{ fmt.Sprint(author.ID), author.Name, }) } return results }, }, }) // SelectOneConfig with remote data resource (async loading) productResource.Meta(&admin.Meta{ Name: "Brand", Config: &admin.SelectOneConfig{ RemoteDataResource: Admin.GetResource("Brand"), SelectMode: "select_async", // or "bottom_sheet" }, }) ``` -------------------------------- ### Configure Remote Selector for Versioned Relationships Source: https://github.com/qor/admin/blob/master/README.md Shows how to implement a remote resource selector for models using publish2.Version. This requires defining a CompositePrimaryKeyField and configuring the ID meta to handle composite keys. ```go type Factory struct { gorm.Model Name string publish2.Version Items []Item `gorm:"many2many:factory_items;association_autoupdate:false"` ItemsSorter sorting.SortableCollection } type Item struct { gorm.Model Name string publish2.Version resource.CompositePrimaryKeyField // Required } func generateRemoteItemSelector(adm *admin.Admin) (res *admin.Resource) { res = adm.AddResource(&Item{}, &admin.Config{Name: "ItemSelector"}) res.IndexAttrs("ID", "Name") res.Meta(&admin.Meta{ Name: "ID", Valuer: func(value interface{}, ctx *qor.Context) interface{} { if r, ok := value.(*Item); ok { return resource.GenCompositePrimaryKey(r.ID, r.GetVersionName()) } return "" }, }) return res } itemSelector := generateRemoteItemSelector(adm) factoryRes.Meta(&admin.Meta{ Name: "Items", Config: &admin.SelectManyConfig{ RemoteDataResource: itemSelector, }, }) ``` -------------------------------- ### Registering Custom Actions in QOR Admin Source: https://context7.com/qor/admin/llms.txt Defines how to create custom actions for records, including batch operations, visibility logic, and external URL redirection. It utilizes the Action struct to define handlers, permissions, and optional input resources. ```go type Action struct { Name string Label string Method string URL func(record interface{}, context *Context) string URLOpenType string Visible func(record interface{}, context *Context) bool Handler func(argument *ActionArgument) error Modes []string Resource *Resource Permission *roles.Permission } productResource.Action(&admin.Action{ Name: "Publish", Label: "Publish Product", Handler: func(arg *admin.ActionArgument) error { for _, record := range arg.FindSelectedRecords() { product := record.(*Product) product.Status = "published" arg.Context.GetDB().Save(product) } return nil }, Modes: []string{"batch", "menu_item"}, }) ``` -------------------------------- ### Configure Select Many Fields in Go Source: https://context7.com/qor/admin/llms.txt Illustrates how to configure 'select_many' meta fields in QOR Admin for multiple-choice selections. This covers using static string arrays and fetching data from remote resources with asynchronous loading capabilities. ```go // SelectManyConfig for multiple selections productResource.Meta(&admin.Meta{ Name: "Tags", Config: &admin.SelectManyConfig{ Collection: []string{"Featured", "Sale", "New Arrival", "Best Seller"}, SelectMode: "select", }, }) // SelectManyConfig with remote data productResource.Meta(&admin.Meta{ Name: "Categories", Config: &admin.SelectManyConfig{ RemoteDataResource: Admin.GetResource("Category"), SelectMode: "select_async", }, }) ``` -------------------------------- ### Generate Remote Manager Selector for Composite Primary Key (Go) Source: https://github.com/qor/admin/blob/master/README.md Generates a remote resource selector for the 'Manager' model, specifically configuring the 'ID' meta to support composite primary keys. This is essential for correctly handling relationships with versioned resources. ```go func generateRemoteManagerSelector(adm *admin.Admin) (res *admin.Resource) { res = adm.AddResource(&Manager{}, &admin.Config{Name: "ManagerSelector"}) res.IndexAttrs("ID", "Name") // Required. Convert single ID into composite primary key res.Meta(&admin.Meta{ Name: "ID", Valuer: func(value interface{}, ctx *qor.Context) interface{} { if r, ok := value.(*Manager); ok { // github.com/qor/qor/resource return resource.GenCompositePrimaryKey(r.ID, r.GetVersionName()) } return "" }, }) return res } ``` -------------------------------- ### Define Custom Meta Fields in Go Source: https://context7.com/qor/admin/llms.txt Demonstrates how to define custom meta fields for QOR Admin resources. This includes setting basic attributes like Name, Label, and Type, as well as implementing custom logic for data retrieval (Valuer) and data saving (Setter). It also shows how to use FormattedValuer for custom display and how to configure specialized field types like 'rich_editor'. ```go // Meta struct definition type Meta struct { Name string FieldName string Label string Type string // string, text, number, checkbox, select_one, select_many, etc. Setter func(record interface{}, metaValue *resource.MetaValue, context *qor.Context) Valuer func(record interface{}, context *qor.Context) interface{} FormattedValuer func(record interface{}, context *qor.Context) interface{} Permission *roles.Permission Config MetaConfigInterface Collection interface{} Resource *Resource } // Register custom meta for a field productResource.Meta(&admin.Meta{ Name: "Price", Label: "Product Price ($)", Type: "number", }) // Meta with custom valuer and setter productResource.Meta(&admin.Meta{ Name: "FullName", Label: "Full Name", Valuer: func(record interface{}, context *qor.Context) interface{} { user := record.(*User) return user.FirstName + " " + user.LastName }, Setter: func(record interface{}, metaValue *resource.MetaValue, context *qor.Context) { // Custom setter logic }, }) // Meta with formatted valuer for display productResource.Meta(&admin.Meta{ Name: "Price", FormattedValuer: func(record interface{}, context *qor.Context) interface{} { product := record.(*Product) return fmt.Sprintf("$%.2f", product.Price) }, }) // Rich text editor meta productResource.Meta(&admin.Meta{ Name: "Description", Type: "rich_editor", }) ``` -------------------------------- ### Overwrite Collection for SelectMany with Composite Primary Key (Go) Source: https://github.com/qor/admin/blob/master/README.md Demonstrates how to overwrite the 'Collection' function for a 'SelectMany' meta (e.g., 'Items') in the 'Factory' resource. It ensures that composite primary keys are used when returning associated items, which is necessary for versioned associations. ```go factoryRes.Meta(&admin.Meta{ Name: "Items", Config: &admin.SelectManyConfig{ Collection: func(value interface{}, ctx *qor.Context) (results [][]string) { if c, ok := value.(*Factory); ok { var items []Item ctx.GetDB().Model(c).Related(&items, "Items") for _, p := range items { // The first element must be the composite primary key instead of ID results = append(results, []string{resource.GenCompositePrimaryKey(p.ID, p.GetVersionName()), p.Name}) } } return }, RemoteDataResource: itemSelector, }, }) ``` -------------------------------- ### Define Factory and Manager Models for Has-One Relationship (Go) Source: https://github.com/qor/admin/blob/master/README.md Defines the 'Factory' and 'Manager' structs for a has-one relationship. The 'Manager' struct includes 'resource.CompositePrimaryKeyField' to support composite primary keys, which is crucial for versioned resources. ```go type Factory struct { gorm.Model Name string publish2.Version ManagerID uint ManagerVersionName string // Required. in "xxxVersionName" format. Manager Manager } type Manager struct { gorm.Model Name string publish2.Version // github.com/qor/qor/resource resource.CompositePrimaryKeyField // Required } ``` -------------------------------- ### Registering Custom Routes for Extended Functionality in Go Source: https://context7.com/qor/admin/llms.txt Extends QOR Admin functionality by registering custom routes beyond standard CRUD operations. This allows for implementing specific actions like data export or bulk imports. It uses the `RegisterRoute` method on a resource, accepting HTTP methods, paths, handler functions, and optional route configurations for permissions. ```go package main import ( "encoding/csv" "fmt" "net/http" "github.com/qor/admin" "github.com/qor/roles" ) // Assuming Product struct and parseFloat function are defined elsewhere // Register custom GET route productResource.RegisterRoute("GET", "/export", func(context *admin.Context) { products, _ := context.FindMany() // Generate CSV context.Writer.Header().Set("Content-Type", "text/csv") context.Writer.Header().Set("Content-Disposition", "attachment; filename=products.csv") writer := csv.NewWriter(context.Writer) writer.Write([]string{"ID", "Name", "Price"}) for _, p := range products.([]*Product) { writer.Write([]string{ fmt.Sprint(p.ID), p.Name, fmt.Sprintf("%.2f", p.Price), }) } writer.Flush() }, &admin.RouteConfig{ PermissionMode: roles.Read, }) // Register custom POST route productResource.RegisterRoute("POST", "/bulk-import", func(context *admin.Context) { file, _, _ := context.Request.FormFile("file") defer file.Close() // Process import reader := csv.NewReader(file) records, _ := reader.ReadAll() for _, record := range records[1:] { // Skip header product := &Product{ Name: record[0], Price: parseFloat(record[1]), } context.GetDB().Create(product) } context.Flash("Import completed successfully", "success") http.Redirect(context.Writer, context.Request, context.URLFor(&Product{}, productResource), http.StatusFound) }, &admin.RouteConfig{ PermissionMode: roles.Create, }) ``` -------------------------------- ### Registering Middleware for Request Processing in Go Source: https://context7.com/qor/admin/llms.txt Adds middleware functions to the QOR Admin router for request processing, logging, or custom authorization. Middleware can intercept requests and responses, modify context, or perform actions before or after the main request handler. Dependencies include the 'time' and 'log' packages. ```go package main import ( "log" "net/http" "time" "github.com/qor/admin" "github.com/qor/roles" ) // Middleware struct type Middleware struct { Name string Handler func(*Context, *Middleware) } // Get router and register middleware router := Admin.GetRouter() // Logging middleware router.Use(&admin.Middleware{ Name: "logger", Handler: func(context *admin.Context, middleware *admin.Middleware) { start := time.Now() // Call next middleware middleware.Next(context) // Log after request log.Printf("[%s] %s - %v", context.Request.Method, context.Request.URL.Path, time.Since(start), ) }, }) // Authorization middleware router.Use(&admin.Middleware{ Name: "authorization", Handler: func(context *admin.Context, middleware *admin.Middleware) { user := context.CurrentUser if user != nil && context.Resource != nil { // Check custom permissions if !hasPermission(user, context.Resource.Name, context.Request.Method) { context.Writer.WriteHeader(http.StatusForbidden) context.Writer.Write([]byte("Access denied")) return } } middleware.Next(context) }, }) // Print all registered routes router.PrintRoutes() ``` -------------------------------- ### Registering Filters for Advanced Filtering in Go Source: https://context7.com/qor/admin/llms.txt Defines and registers various types of filters (text, number, select, custom) for advanced data filtering within the QOR admin panel. It utilizes a Filter struct and allows for custom handlers to define complex filtering logic. ```go // Filter struct definition type Filter struct { Name string Label string Type string Operations []string // eq, cont, gt, gteq, lt, lteq, present, blank Resource *Resource Visible func(context *Context) bool Handler func(*gorm.DB, *FilterArgument) *gorm.DB Config FilterConfigInterface } // Basic text filter productResource.Filter(&admin.Filter{ Name: "Name", Label: "Product Name", Operations: []string{"contains", "eq"}, }) // Number filter with operations productResource.Filter(&admin.Filter{ Name: "Price", Type: "number", Operations: []string{"eq", "gt", "lt", "gteq", "lteq"}, }) // Select one filter productResource.Filter(&admin.Filter{ Name: "Status", Config: &admin.SelectOneConfig{ Collection: [][]string{ {"draft", "Draft"}, {"published", "Published"}, {"archived", "Archived"}, }, }, }) // Select many filter productResource.Filter(&admin.Filter{ Name: "Categories", Config: &admin.SelectManyConfig{ RemoteDataResource: Admin.GetResource("Category"), }, }) // Custom filter handler productResource.Filter(&admin.Filter{ Name: "PriceRange", Label: "Price Range", Type: "string", Handler: func(db *gorm.DB, arg *admin.FilterArgument) *gorm.DB { if value := arg.Value.Get("Value"); value != nil { switch value.Value.(string) { case "low": return db.Where("price < ?", 50) case "medium": return db.Where("price >= ? AND price < ?", 50, 200) case "high": return db.Where("price >= ?", 200) } } return db }, }) ``` -------------------------------- ### Adding Sub-Resources for Nested Relationships in Go Source: https://context7.com/qor/admin/llms.txt Registers nested resources within the QOR Admin interface to manage relationships, such as has-many associations. This allows for hierarchical data management and navigation. It requires defining GORM models for the main and sub-resources and using the `AddSubResource` method on the parent resource. ```go package main import ( "github.com/jinzhu/gorm" "github.com/qor/admin" ) type Order struct { gorm.Model UserID uint TotalPrice float64 Items []OrderItem } type OrderItem struct { gorm.Model OrderID uint ProductID uint Quantity int Price float64 } // Register main resource orderResource := Admin.AddResource(&Order{}) // Add sub-resource for order items itemResource, err := orderResource.AddSubResource("Items", &admin.Config{ Name: "Order Items", }) if err == nil { itemResource.IndexAttrs("Product", "Quantity", "Price") itemResource.EditAttrs("Product", "Quantity", "Price") } // Sub-resources are accessible via nested routes: // GET /admin/orders/:order_id/order_items // GET /admin/orders/:order_id/order_items/:order_item_id // POST /admin/orders/:order_id/order_items // PUT /admin/orders/:order_id/order_items/:order_item_id // DELETE /admin/orders/:order_id/order_items/:order_item_id ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.