go-rel / rel

:gem: Modern ORM for Golang - Testable, Extendable and Crafted Into a Clean and Elegant API
https://go-rel.github.io/
MIT License
762 stars 56 forks source link

Add support for embedded no anonymous fields #277

Closed qRoC closed 2 years ago

qRoC commented 2 years ago

Change

// struct without primary key is a field
// TODO: test by scanner/valuer instead?
if pk, _ := searchPrimary(typ); len(pk) == 0 {
    data.fields = append(data.fields, name)
    continue
}

If struct implement scanner/valuer - is field, else is embedded

Fs02 commented 2 years ago

Hi, thanks for posting this issue

can you elaborate more about what you want to do?

qRoC commented 2 years ago

can you elaborate more about what you want to do?

Embeddable :)

type Price struct {
    Amount f64
    Currency string
}

type Product struct {
    ID int
    Title string
    Price Price
}

Table:

id
title
price_amount
price_currency
Fs02 commented 2 years ago

I see, that make sense I guess for the API, we need to declare it as embedded explicitly using struct tag

following existing convention: https://go-rel.github.io/basics/#embedded-structs I think following combination is possible:

note: embedded structag is required for named embedding

what do you think? (and let me know if you are willing to send a PR for this 😄 )

qRoC commented 2 years ago

What are the reasons why a structag is needed? In the current API we can detect is embedded or association or custom type(valuer)

Fs02 commented 2 years ago

one reason is for explicitness, so other people who read the code can know that it's an embedded field without guessing or looking deep to the documentation

another reason is this idea can be expanded in the future, we can have another utility tag beside embedded to do something else. for example db:",embedded_json" tag to encode/decode the field as json text

qRoC commented 2 years ago

other people who read the code can know that it's an embedded field without guessing or looking deep to the documentation

But for association this rule does not work:

type User struct {
    Address Address // association or custom type(valuer) ?
}
Fs02 commented 2 years ago

that's right,

but I think we can see association as default behavior. when there's a field with struct type (except time), it's easier to think it's as association at first where for embedded object, we need to check the content of struct first, and maybe some people may also add comment to the field declaration

type Product struct {
    ID int
    Title string

        // prefer people to do (2) rather than (1)

        // embedded field of price_*                    <- (1)
    Price Price

        Price Price `db:"price_,embedded"`          <- (2)
}