Code Monkey home page Code Monkey logo

Comments (5)

dhax avatar dhax commented on August 17, 2024

I think you are assigning a report model with its nil values to data because of the casting of nil pointer to a report under ctxReport, so id might be always 0. You are trying to insert the report returned from your database and not from the request. The Bind() method is where the request ist parsed into data.

func (rs *ReportResource) insert(w http.ResponseWriter, r *http.Request) {
p := r.Context().Value(ctxReport).(*models.Report)
data := &reportRequest{Report: p}

Please try this instead:

func (rs *ReportResource) insert(w http.ResponseWriter, r *http.Request) {
data := &reportRequest{}

from go-base.

dhax avatar dhax commented on August 17, 2024

closing for now due to inactivity, feel free to reopen if your problem still exists...

from go-base.

karfianto avatar karfianto commented on August 17, 2024

Hi, as a new learner, I think its good to provide at least one example of create/insert just to make it easy to learn and ready to use.

Thanks

from go-base.

karfianto avatar karfianto commented on August 17, 2024

I got this response when post a new record

{
    "status": "Internal Server Error"
}

Here's what I've done

app/api.go

// Package app ties together application resources and handlers.
package app

import (
	"net/http"

	"github.com/go-chi/chi"
	"github.com/go-pg/pg"
	"github.com/sirupsen/logrus"

	"github.com/dhax/go-base/database"
	"github.com/dhax/go-base/logging"
)

type ctxKey int

const (
	ctxAccount ctxKey = iota
	ctxProfile
	ctxReport
)

// API provides application resources and handlers.
type API struct {
	Account *AccountResource
	Profile *ProfileResource
	Report *ReportResource
}

// NewAPI configures and returns application API.
func NewAPI(db *pg.DB) (*API, error) {
	accountStore := database.NewAccountStore(db)
	account := NewAccountResource(accountStore)

	profileStore := database.NewProfileStore(db)
	profile := NewProfileResource(profileStore)

	reportStore := database.NewReportStore(db)
	report := NewReportResource(reportStore)

	api := &API{
		Account: account,
		Profile: profile,
		Report: report,
	}
	return api, nil
}

// Router provides application routes.
func (a *API) Router() *chi.Mux {
	r := chi.NewRouter()

	r.Mount("/account", a.Account.router())
	r.Mount("/profile", a.Profile.router())
	r.Mount("/report", a.Report.router())

	return r
}

func log(r *http.Request) logrus.FieldLogger {
	return logging.GetLogEntry(r)
}

app/report.go

package app

import (
	"context"
	"errors"
	"github.com/dhax/go-base/auth/jwt"
	"github.com/dhax/go-base/models"
	"github.com/go-chi/chi"
	"github.com/go-chi/render"
	"net/http"
)

// The list of error types returned from account resource.
var (
	ErrReportValidation = errors.New("report validation error")
)

// ReportStore defines database operations for a report.
type ReportStore interface {
	Get(accountID int) (*models.Report, error)
	Create(*models.Report) error
}

// ReportResource implements report management handler.
type ReportResource struct {
	Store ReportStore
}

// NewReportResource creates and returns a report resource.
func NewReportResource(store ReportStore) *ReportResource {
	return &ReportResource{
		Store: store,
	}
}

func (rs *ReportResource) router() *chi.Mux {
	r := chi.NewRouter()
	r.Use(rs.reportCtx)
	r.Get("/", rs.get)
	r.Post("/", rs.create)
	//r.Put("/", rs.update)
	return r
}

func (rs *ReportResource) reportCtx(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		claims := jwt.ClaimsFromCtx(r.Context())
		p, err := rs.Store.Get(claims.ID)
		if err != nil {
			log(r).WithField("reportCtx", claims.Sub).Error(err)
			render.Render(w, r, ErrInternalServerError)
			return
		}

		ctx := context.WithValue(r.Context(), ctxReport, p)
		next.ServeHTTP(w, r.WithContext(ctx))
	})
}

type reportRequest struct {
	*models.Report
}

func (d *reportRequest) Bind(r *http.Request) error {
	return nil
}

type reportResponse struct {
	*models.Report
}

func newReportResponse(p *models.Report) *reportResponse {
	return &reportResponse{
		Report: p,
	}

}

func (rs *ReportResource) get(w http.ResponseWriter, r *http.Request) {
	p := r.Context().Value(ctxReport).(*models.Report)
	render.Respond(w, r, newReportResponse(p))
}

func (rs *ReportResource) create(w http.ResponseWriter, r *http.Request) {
	data := &reportRequest{}
	if err := render.Bind(r, data); err != nil {
		render.Render(w, r, ErrInvalidRequest(err))
	}

	if err := rs.Store.Create(data.Report); err != nil {
		//switch err.(type) {
		//case validation.Errors:
		//	render.Render(w, r, ErrValidation(ErrReportValidation, err.(validation.Errors)))
		//	return
		//}
		render.Render(w, r, ErrRender(err))
		return
	}
	render.Respond(w, r, http.StatusOK)
}

database/reportStore.go

package database

import (
	"github.com/dhax/go-base/models"
	"github.com/go-pg/pg"
	//"database/sql"
	"log"
)

// ReportStore implements database operations for profile management.
type ReportStore struct {
	db *pg.DB
}

// NewProfileStore returns a ReportStore implementation.
func NewReportStore(db *pg.DB) *ReportStore {
	return &ReportStore{
		db: db,
	}
}

// Get gets a report by account ID.
func (s *ReportStore) Get(accountID int) (*models.Report, error) {
	p := models.Report{AccountID: accountID}
	_, err := s.db.Model(&p).
		Where("account_id = ?", accountID).
		SelectOrInsert()

	return &p, err
}

// Update report .
func (s *ReportStore) Update(p *models.Report) error {
	err := s.db.Update(p)
	return err
}


// Create inserts the Reports to the database.
func (s *ReportStore) Create(p *models.Report) error {
	err := s.db.Insert(p)
	log.Println(p)
	if err != nil {
		return err
	}
	return err
}

models/report.go

// Package models contains application specific entities.
package models

import (
	"database/sql"
	"github.com/go-ozzo/ozzo-validation"
	"time"
	//"github.com/pkg/errors"

)

// Profile holds specific application settings linked to an Account.
type Report struct {
	// Reports represents public.reports
	Id              int   `sql:",pk,unique"`          // id
	AccountID       int   // account_id
	UpdatedAt       time.Time      // date
	Temperature     sql.NullFloat64 // temperature
	Cough           bool            // cough
	RunningNose     bool            // running_nose
	SoreThroat      bool            // sore_throat
	DifficultBreath bool            // difficult_breath
	Headache        bool            // headache
	Diarrhea        bool            // diarrhea
	Nausea          bool            // nausea
	VitA            bool            // vit_a
	VitE            bool            // vit_e
	VitD            bool            // vit_d
	VitC            bool            // vit_c
	Sunbathe        bool            // sunbathe
	Exercise        bool            // exercise
	Veg             bool            // veg
	Fruit           bool            // fruit
	SleepEarly      bool            // sleep_early
	Mask            bool            // mask
	Handwash        bool            // handwash
	Complaint       sql.NullString  // complaint
	Medicine        sql.NullString  // medicine
}

// Validate validates Profile struct and returns validation errors.
func (p *Report) Validate() error {

	return validation.ValidateStruct(p,
		validation.Field(&p.AccountID, validation.Required),
	)
}

from go-base.

dhax avatar dhax commented on August 17, 2024

a complete CRUD example can be found at the admin routes, managing accounts here

from go-base.

Related Issues (11)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.