-
Notifications
You must be signed in to change notification settings - Fork 11.4k
[10.x] Add insertWithCasts()
to Eloquent Builder
#46798
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
Closed
Closed
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about the following setup:
This uses more of the Eloquent methods and is more of a
createMany
function (it isn't that much different from your code actually). AlsogetAttributes()
is used internally to create insert statements:framework/src/Illuminate/Database/Eloquent/Model.php
Line 1297 in 997218b
(which routes to the public fn
getAttributes()
)There are some remaining questions with triggering the events though, e.g. what happens when one event returns false? In current situations, the update fails so it might be wise to use the same thing here.
Also the
unguarded()
wrapper can probably be removed since I believe its expected to be guarded by default. You can wrap it yourself in the outer function:Just spouting some ideas here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bert-w thanks for the thoughtful comments!
Timestamps
I wanted to avoid creating a new set of timestamps for something that would essentially be static across all of the models being inserted. Not a make or break, and would be amenable to making that change. Just seemed like unnecessary overhead.
Use of unguarded()
This is here so that the call to
Model@fill()
doesn't discard attributes that are being passed intonewModelInstance()
, even if they are guarded. If we were to change it tocreateMany
then that'd be great and would happily implement your suggestion. 👍The way
Builder@insert()
works is that it let's you pass anything to be inserted, guarded or not. I was just keeping with that convention.An aside
There's also an issue I never noticed before, which is if you pass two arrays that have different keys, MySQL throws an exception.
(I feel there should be a PR for adding a DEFAULT value to an insert/update/etc statement, but well beyond the scope of this PR).
I guess we'll wait to see what the framework maintainers say. I think this could also be improved by letting the caller pass an array or collection of models that need persisted (in case they need to set the state with their own Model methods or something).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just realized, I don't think you can get the last inserted ID for a for multiple records inserted in a single INSERT statement.
So we wouldn't be able to write
createMany()
(that emits events) unless we did them one by one.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there's actually an interesting workaround: you can use last-inserted-id to get the id of the first row of the last batch. Since the batch is one atomic query, the ids are bound to be sequential (assuming mysql+innodb) so the other rows can be simply calculated. But this might introduce inconsistencies across other db drivers since im not sure what happens there (however the integration test should cover it since it runs for all supported db drivers).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a bit too presumptuous I'm afraid. Within MySQL, you can actually change your auto-increment increment value to something other than 1.
I don't know a lot about PostgreSQL, but I think that engine allows for a SERIAL column type for specifying how you might want to auto-increment.