Let's Go احراز هویت کاربر › ایجاد مدل کاربران
قبلی · فهرست · بعدی
فصل 10.2.

ایجاد مدل کاربران (Creating a Users Model)

در این بخش، نحوه ایجاد مدل کاربران (Users Model) را بررسی می‌کنیم. این شامل ساختار داده (Data Structure)، متدهای دسترسی (Access Methods) و عملیات پایگاه داده (Database Operations) می‌شود.

برای شروع، بیایید یک جدول کاربران (Users Table) در پایگاه داده (Database) خود ایجاد کنیم:

USE snippetbox;

CREATE TABLE users (
    id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(255) NOT NULL,
    email VARCHAR(255) NOT NULL,
    hashed_password CHAR(60) NOT NULL,
    created DATETIME NOT NULL
);

ALTER TABLE users ADD CONSTRAINT users_uc_email UNIQUE (email);

چند نکته در مورد این جدول وجود دارد:

ساخت مدل در Go

سپس بیایید یک مدل تنظیم کنیم تا بتوانیم به راحتی با جدول جدید users کار کنیم. ما همان الگویی را که قبلاً در کتاب برای مدل‌سازی دسترسی به جدول snippets استفاده کرده‌ایم، دنبال خواهیم کرد، بنابراین امیدواریم که این کار آشنا و ساده باشد.

ابتدا فایل internal/models/errors.go را که قبلاً ایجاد کرده‌اید باز کنید و چند نوع خطای جدید تعریف کنید:

File: internal/models/errors.go
package models

import (
    "errors"
)

var (
    ErrNoRecord = errors.New("models: no matching record found")

    // Add a new ErrInvalidCredentials error. We'll use this later if a user
    // tries to login with an incorrect email address or password.
    ErrInvalidCredentials = errors.New("models: invalid credentials")

    // Add a new ErrDuplicateEmail error. We'll use this later if a user
    // tries to signup with an email address that's already in use.
    ErrDuplicateEmail = errors.New("models: duplicate email")
)

سپس یک فایل جدید در internal/models/users.go ایجاد کنید:

$ touch internal/models/users.go

…و یک ساختار جدید User (برای نگهداری داده‌های یک کاربر خاص) و یک ساختار UserModel (با برخی متدهای جایگزین برای تعامل با پایگاه داده ما) تعریف کنید. به این صورت:

File: internal/models/users.go
package models

import (
    "database/sql"
    "time"
)

// Define a new User struct. Notice how the field names and types align
// with the columns in the database "users" table?
type User struct {
    ID             int
    Name           string
    Email          string
    HashedPassword []byte
    Created        time.Time
}

// Define a new UserModel struct which wraps a database connection pool.
type UserModel struct {
    DB *sql.DB
}

// We'll use the Insert method to add a new record to the "users" table.
func (m *UserModel) Insert(name, email, password string) error {
    return nil
}

// We'll use the Authenticate method to verify whether a user exists with
// the provided email address and password. This will return the relevant
// user ID if they do.
func (m *UserModel) Authenticate(email, password string) (int, error) {
    return 0, nil
}

// We'll use the Exists method to check if a user exists with a specific ID.
func (m *UserModel) Exists(id int) (bool, error) {
    return false, nil
}

مرحله نهایی اضافه کردن یک فیلد جدید به ساختار application است تا بتوانیم این مدل را در دسترس هندلرهای خود قرار دهیم. فایل main.go را به صورت زیر به‌روزرسانی کنید:

File: cmd/web/main.go
package main

...

// Add a new users field to the application struct.
type application struct {
    logger        *slog.Logger
    snippets       *models.SnippetModel
    users          *models.UserModel
    templateCache  map[string]*template.Template
    formDecoder    *form.Decoder
    sessionManager *scs.SessionManager
}

func main() {
    
    ...

    // Initialize a models.UserModel instance and add it to the application
    // dependencies.
    app := &application{
        logger:         logger,
        snippets:       &models.SnippetModel{DB: db},
        users:          &models.UserModel{DB: db},
        templateCache:  templateCache,
        formDecoder:    formDecoder,
        sessionManager: sessionManager,
    }

    tlsConfig := &tls.Config{
        CurvePreferences: []tls.CurveID{tls.X25519, tls.CurveP256},
    }

    srv := &http.Server{
        Addr:         *addr,
        Handler:      app.routes(),
        ErrorLog:     slog.NewLogLogger(logger.Handler(), slog.LevelError),
        TLSConfig:    tlsConfig,
        IdleTimeout:  time.Minute,
        ReadTimeout:  5 * time.Second,
        WriteTimeout: 10 * time.Second,
    }

    logger.Info("starting server", "addr", srv.Addr)

    err = srv.ListenAndServeTLS("./tls/cert.pem", "./tls/key.pem")
    logger.Error(err.Error())
    os.Exit(1)
}

...

اطمینان حاصل کنید که همه فایل‌ها ذخیره شده‌اند، سپس برنامه را اجرا کنید. در این مرحله باید متوجه شوید که بدون هیچ مشکلی کامپایل می‌شود.

واژه‌نامه اصطلاحات فنی

اصطلاح فارسی معادل انگلیسی توضیح
مدل کاربران Users Model ساختار داده برای کاربران
ساختار داده Data Structure الگوی سازماندهی داده‌ها
متدهای دسترسی Access Methods توابع دسترسی به داده‌ها
عملیات پایگاه داده Database Operations دستورات کار با پایگاه داده
جدول کاربران Users Table جدول ذخیره اطلاعات کاربران
پایگاه داده Database محل ذخیره‌سازی داده‌ها
رکورد کاربر User Record اطلاعات یک کاربر
درج داده Data Insertion افزودن داده جدید
بازیابی داده Data Retrieval خواندن داده از پایگاه داده
به‌روزرسانی داده Data Update تغییر داده موجود