Skip to content
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

updateOrCreate on belongsTo relationship not working as expected #29978

Closed
ThaDaVos opened this issue Sep 13, 2019 · 11 comments
Closed

updateOrCreate on belongsTo relationship not working as expected #29978

ThaDaVos opened this issue Sep 13, 2019 · 11 comments

Comments

@ThaDaVos
Copy link

  • Lumen Version: 5.8.*
  • Laravel Version: 5.8.*
  • PHP Version: 7.3.*
  • Database Driver & Version: MySql 5.7.*

Description:

When trying to use the updateOrCreate method on a belongsTo relationship it's not working as expected: When there's no records, it creates one succesfully but it doesn't assign the id in the foreignkey field, when I know there's a record it just creates a new one because it can't match based on the id because the foreignkey isn't being set I also see the following in the query logs which will always return nothing because 0 is never equal to 1:

select * from models where 0 = 1....

Is this caused because the belongsTo doesn't have an implementation for the updateOrCreate as hasManyThrough in this issue: #16758

Steps To Reproduce:

  • Create two tables with a belongsTo relationship from one to the other, for example ModelA belongs to ModelB
  • Create new ModelA and then try to updateOrCreate the related model like:
// Below will create a new ModelA and insert a new modelB but if you check the database the foreignkey for ModelB in ModelA will not be set
$modelA = ModelA::updateOrCreate([ 'id' => 1 ], [ 'field1' => 'Bla' ]);
$modelA->modelB()->updateOrCreate([ 'field1' => 'Hello' ], [ 'field2' => 'World' ]);
  • Retrieve ModelA and try to update ModelB like:
$modelA = ModelA::where('id', 1)->first(); // just assume it returns a modelA
$modelA->modelB()->updateOrCreate(['field1' => 'Hello'], ['field2' => 'Country']); 
// this will always create a new row because the query will never find a matching ModelB because the foreignkey has never been set
  • Rinse and repeat the above step and see many ModelB's appear in your database...
@ThaDaVos
Copy link
Author

Also posted it here because I didn't know from which framework it comes: laravel/lumen-framework#967

@driesvints
Copy link
Member

Hmm not really sure what's going on here. Appreciating any help with figuring this out.

@ThaDaVos
Copy link
Author

A friend of mine said it's probably using _call to call the function because it doesn't exist on the belongsTo relation -> currenlty I worked arround it by setting the foreignkeys manually and then it seems to work, but I don't know why it isn't setting them itself

@staudenmeir
Copy link
Contributor

I'm not sure if this is supposed to work. I think updateOrCreate() really only makes sense for relationships where the foreign key is in the related or pivot table.

You can call ModelB::updateOrCreate() separately and then set the foreign key with BelongsTo::associate().

@ThaDaVos
Copy link
Author

But one would expect it to work on both sides of the relationship, don't they?

@staudenmeir
Copy link
Contributor

IMO, updateOrCreate() really only makes sense in one direction here.

@ThaDaVos
Copy link
Author

Then maybe throw an error when used wrongly instead of having the create part work?

@driesvints
Copy link
Member

@dvdbot might be a good update but sounds like that's more of a feature request. Feel free to open up an issue on the ideas repo.

@epixian
Copy link

epixian commented Oct 4, 2019

The whole beauty of Eloquent is in its relationships. belongsTo() returns a query builder just like every other relationship, and the documentation for create() is not currently worded to suggest that it doesn't work with certain relationships.

@tripleten
Copy link

+1

@troygilbert
Copy link

I got bit by this myself. The comments above about why it's not working (because the BelongsTo relation doesn't implement create()) are correct. But I can't figure out why it shouldn't work. This seems like a clear bug to me. What am I missing?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants