laravel-mongodb
laravel-mongodb copied to clipboard
Add cast support
Fixes #2199 , #1580
Hello,
Can you please add a tests?
Thanks!
@divine @Christophvh I really need this feature merged ASAP, I've created an issue regarding this which is likely related and after manually taking the small if
statement from the attached verified commit and manually adding it to my code, I can indeed see that it's casting my field to an integer. Any idea when this can be merged?
@sts-ryan-holton honestly, probably never.
@divine how can I get this into my project? It's just a few lines of code and seems to work for me
@divine how can I get this into my project? It's just a few lines of code and seems to work for me
It's just two lines without a test that could break any application.
How you can get into this project? Well, it's currently in stale mode as I can't merge and release PRs that were created back in March.
Thanks!
Hi @sts-ryan-holton , could you try to add some tests ? You can open a new PR
I guess it is fixed and this issue no longer exists. If it still exists, please let me know how I can produce it. @Giacomo92 @sts-ryan-holton
Ran into this today and still isn't working. Using v4.0.
Pulling a row of data from a csv file and simply running an updateOrCreate() on the model. The subject_id and subject_expeditionId are still entered into the document as strings.
/**
* The attributes that should be cast.
*
* @var array
*/
protected $casts = [
'subject_id' => 'integer',
'subject_expeditionId' => 'integer',
'created_at' => 'datetime',
'updated_at' => 'datetime',
];
Handling it by adding mutators in my models for every place I need it. For example:
/**
* Set subjectId to int.
*/
protected function subjectId(): Attribute
{
return Attribute::make(
set: fn (string $value) => (int)$value,
);
}
@rbruhn can you please create a new issue? I just ran a quick test and it worked just fine. A small test case would help us tremendously. You can use some other tests in ModelTest
as guidance on how to create them.
I'm closing this pull request as setAttribute
handles a bit of special logic (casting for identifiers and access to nested fields), then defers to the default implementation in the Eloquent model, so anything that works in Eloquent by default should also work here just the same.
parent::setAttribute()
doesn't handle normal casting. If you look closely, it only handles mutators, dates, enums, classes, json, encrypted, and hashed. The code @Christophvh added fixes the problem.
I did a few quick tests of my own. They come back correct, (assertIsInt() and assertIsString()) but still stored in the database incorrectly. I believe the test results are showing the getAttribute but not setting correctly before inserting in the database.
@alcaeus I was checking this problem a couple of days ago. It's really not working. As mentioned in #2393, if you don't cast your values before storing them in the DB, they will be stored as their original data type. To produce this issue, you can test int
or bool
data type for casting like this:
public function testCastingAttributes(): void {
Birthday::truncate();
Birthday::query()->create(['name' => 'Hans','age' => '1']);
self::assertIsBool(Birthday::query()->first()->age); // pass
self::assertIsBool(DB::collection('birthday')->first()['age']); // fail
}
Don't forget to add
age
attribute asbool
data type in$casting
But with this PR, it's working fine. If you agree, I will work on this issue and write some tests to ensure everything is okay and all data types casting works fine.