-
-
Notifications
You must be signed in to change notification settings - Fork 239
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rel:has-one
on a relationship should not have foreign key creation
#1115
Comments
I’m not familiar with the code related to migration. 😂 |
I've created a PR for this. |
The example in the documentation doesn’t seem quite appropriate. If it’s a has-one relationship, we should store the Profile ID in the User table instead. // Profile belongs to User.
type Profile struct {
ID int64 `bun:",pk"`
Lang string
}
type User struct {
ID int64 `bun:",pk"`
Name string
ProfileID string
Profile *Profile `bun:"rel:has-one,join:profile_id=id"`
} In this example, we need to create a foreign key, like If it's a belong-to relationship, we should store the user's id in the profile table. // Profile belongs to User.
type Profile struct {
ID int64 `bun:",pk"`
Lang string
UserID string
User *User `bun:"rel:belong-to,join:user_id=id"`
}
type User struct {
ID int64 `bun:",pk"`
Name string
} In this example, we need to create a foreign key, like @vmihailenco Is there anyone familiar with this area who can provide guidance? |
Thank you for your PR; it helped me understand the key logic. |
@j2gg0s However, similar to has-many, it would be useful if has-one could also be referenced within the parent struct.
|
New Tag to disable FK? |
I agree that the documentation needs to be clearer, but I wouldn't say it's not appropriate. Going by the doc's idea, we want to have one profile per user. And each profile should belong to a user. And for this, the columns are actually correct, it just doesn't have the relations. So the complete version would be: type Profile struct {
ID int64 `bun:",pk"`
Lang string
UserID int64
User *User `bun:"belongs-to,join=user_id=id"` // this should have been in the docs
}
type User struct {
ID int64 `bun:",pk"`
Name string
Profile *Profile `bun:"rel:has-one,join:id=user_id"`
} Otherwise, the docs are good, only the foreign key creation. The reason, from the profile's perspective, it is already satisfied that there can only be one user because it refers to the user model. And as such, it is correctly creating the foreign key for the In summary, the docs are good, just a little incomplete. Problem is the foreign key creation on the user. |
Hi everyone! Finally had the time to dig into this and here's what I think. TL;DR: As far as I understand, @dordieux I also added a short comment to your PR, but I'm writing a more detailed version here. I'd love to hear your thoughts on that!
So this has sent me reading the docs for ORM: Table relationships, and, interestingly enough, words "foreign key" aren't mentioned anywhere on that page. 😄 It looks to me like In that light the example doesn't seem inappropriate at all --
Which is why I also disagree with this. The choice between type User struct {
ID int64 `bun:",pk"`
ProfileID string
Profile *Profile `bun:"rel:has-one,join:profile_id=id"`
} Calling
Right, I think that's a correct impression. However, it doesn't necessarily mean we shouldn't create FKs for
Precisely, but it is a problem for a different reason (i.e. not because it's a CREATE TABLE users (
id BIGINT PRIMARY KEY,
FOREIGN KEY (id) REFERENCES profiles.user_id
); Having a PRIMARY KEY column reference another column is wrong and not intended, which is something we can rather safely assume from the The solution: do not create foreign keys for
We have create.WithForeignKeys() // create FKs for all Relations
create.WithForeignKeys("Profile", "Avatar") // create FKs for Profile and Avatar relations, ignore all others This change should also be backwards compatible. Out of this ticket's scope though. |
I was writing a function to generate the create table statements with the foreign keys and it was working fine...until I found out that I had a
has-one
relationship.I was under the impression that
has-one
was meant to be used in place ofhas-many
to deal with a one-to-one relationship. Example copied from the docs:It says right there that the Profile belongs to the user and that is what should refer to the User not the other way around. But currently, when trying to use the
bun.CreateTableQuery.WithForeignKeys()
, it is creating a foreign key likeFOREIGN KEY ("id") REFERENCES "profiles" ("user_id")
on the User table.Also, as I have a
belongs-to
relationship on the Profile model, it is correctly creating the foreign key to reference the User table. The issue is that the other one should not be created.The text was updated successfully, but these errors were encountered: