Skip to content

feat: [#635] Optimize the process of generating migration and model#998

Merged
krishankumar01 merged 43 commits intomasterfrom
kkumar-gcc/#635
May 12, 2025
Merged

feat: [#635] Optimize the process of generating migration and model#998
krishankumar01 merged 43 commits intomasterfrom
kkumar-gcc/#635

Conversation

@krishankumar01
Copy link
Member

@krishankumar01 krishankumar01 commented Apr 9, 2025

📑 Description

Closes goravel/goravel#635

This PR introduces support for generating a model directly from an existing database table using the --table option.

go run . artisan make:model --table=users -f User

Example

Given the following table definition:

return facades.Schema().Create("users", func(table schema.Blueprint) {
	table.ID()
	table.String("name").Nullable().Comment("User's full name")
	table.String("email").Comment("User's email address")
	table.String("password").Comment("User's hashed password")
	table.Boolean("is_active").Default(true).Comment("Indicates if the user is active")
	table.Integer("age").Nullable().Comment("User's age")
	table.BigInteger("balance").Default(0).Comment("User's account balance")
	table.Float("rating").Nullable().Comment("User rating score")
	table.Decimal("credits").Default(0.00).Comment("User credits balance")
	table.Enum("role", []any{"admin", "user", "moderator"}).Default("user").Comment("User role")
	table.Json("preferences").Nullable().Comment("User settings in JSON format")
	table.Date("birthdate").Nullable().Comment("User's birthdate")
	table.DateTime("last_login").Nullable().Comment("Last login timestamp")
	table.TimestampTz("created_at_2")
	table.Timestamps(6)
	table.SoftDeletes()
})

Generated Model

package models

import (
	"github.com/goravel/framework/database/orm"
	"github.com/goravel/framework/support/carbon"
)

type User struct {
	orm.Model
	orm.SoftDeletes
	Name        *string          `json:"name" gorm:"column:name"`
	Email       string           `json:"email" gorm:"column:email"`
	Password    string           `json:"password" gorm:"column:password"`
	IsActive    bool             `json:"is_active" gorm:"column:is_active"`
	Age         *int             `json:"age" gorm:"column:age"`
	Balance     int64            `json:"balance" gorm:"column:balance"`
	Rating      *float64         `json:"rating" gorm:"column:rating"`
	Credits     float64          `json:"credits" gorm:"column:credits"`
	Role        any              `json:"role" gorm:"column:role"`
	Preferences *string          `json:"preferences" gorm:"column:preferences"`
	Birthdate   *carbon.DateTime `json:"birthdate" gorm:"column:birthdate"`
	LastLogin   *carbon.DateTime `json:"last_login" gorm:"column:last_login"`
	CreatedAt2  carbon.DateTime  `json:"created_at_2" gorm:"column:created_at_2"`
}

func (m *User) TableName() string {
	return "users"
}

Overriding the mapping:

Users can override the default mapping in their app's app/providers/database_service_provider.go:

facades.Schema().Extend(&contractsschema.Extension{
    GoTypes: []contractsschema.GoType{
        {
            Pattern: "uuid", 
            Type: "uuid.UUID", 
            NullType: "uuid.NullUUID", 
            Imports: []string{"github.com/google/uuid"},
        },
        {
            Pattern: "point", 
            Type: "geom.Point", 
            NullType: "*geom.Point", 
            Imports: []string{"github.com/twpayne/go-geom"},
        },
    },
})

✅ Checks

  • Added test cases for my code

@codecov
Copy link

codecov bot commented Apr 9, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 70.35%. Comparing base (f70e4fa) to head (bff4611).
Report is 35 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #998      +/-   ##
==========================================
+ Coverage   69.10%   70.35%   +1.24%     
==========================================
  Files         168      176       +8     
  Lines       11340    12297     +957     
==========================================
+ Hits         7836     8651     +815     
- Misses       3152     3265     +113     
- Partials      352      381      +29     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@krishankumar01 krishankumar01 requested a review from a team as a code owner April 9, 2025 21:20
@krishankumar01 krishankumar01 marked this pull request as draft April 10, 2025 16:27
@krishankumar01 krishankumar01 marked this pull request as ready for review April 13, 2025 13:26
Copy link
Contributor

@hwbrzzl hwbrzzl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Amazing PR 👍

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.50.

Benchmark suite Current: 75c6476 Previous: a232615 Ratio
BenchmarkFile_ReadWrite 284984 ns/op 2073 B/op 28 allocs/op 172419 ns/op 2072 B/op 28 allocs/op 1.65
BenchmarkFile_ReadWrite - ns/op 284984 ns/op 172419 ns/op 1.65

This comment was automatically generated by workflow using github-action-benchmark.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So sorry for the back and forth, due to goravel/goravel#642 (comment), this change may be unnecessary for now. We need a deep investigation into this. We can merge this PR first and create another PR to remove BaseModel, NullableSoftDeletes and NullableTimestamps if you want.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will create a separate PR for this

Copy link
Contributor

@hwbrzzl hwbrzzl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are some issues when testing it locally:

image

}

if column.Autoincrement {
tagParts = append(tagParts, fmt.Sprintf(`gorm:"%s"`, "autoIncrement"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
tagParts = append(tagParts, fmt.Sprintf(`gorm:"%s"`, "autoIncrement"))
tagParts = append(tagParts, fmt.Sprintf(`gorm:"%s"`, "primaryKey"))

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PrimaryKey and AutoIncrement are two separate concepts, right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but a AutoIncrement column should be PrimaryKey.

@krishankumar01
Copy link
Member Author

There are some issues when testing it locally:
image

That first error was my mistake—I renamed NullableModel to BaseModel. In any case, could you please share your migration?

@krishankumar01 krishankumar01 requested a review from hwbrzzl May 11, 2025 07:53
@hwbrzzl
Copy link
Contributor

hwbrzzl commented May 11, 2025

CI failed

Copy link
Contributor

@hwbrzzl hwbrzzl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great PR 👍 LGTM, only nitpicks on the test cases.

Copy link
Contributor

@hwbrzzl hwbrzzl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great 👍 Thanks

@krishankumar01 krishankumar01 merged commit cf77c8a into master May 12, 2025
14 checks passed
@krishankumar01 krishankumar01 deleted the kkumar-gcc/#635 branch May 12, 2025 04:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Optimize the process of generating migration and model

3 participants