String values fail for belongsToJson and HasManyJson
madsem opened this issue · 4 comments
Hey @staudenmeir,
thanks a lot for this package, I have been using it for a while and it was working great.
Today I updated and made some changes to an existing app, so I can't say if the update caused this, or if I am simply doing something wrong...
But in any case, I am using this in conjunction with FilamentPhp table & form builder, which saves JSON values as string...
Before it was working with string values, but now it's not any longer:
use Staudenmeir\EloquentJsonRelations\Relations\HasManyJson;
class LanderOfferSet extends Model
{
use \Staudenmeir\EloquentJsonRelations\HasJsonRelationships;
protected $casts = [
'offers' => 'json',
];
public function landers(): HasManyJson
{
return $this->hasManyJson(Lander::class, 'lander_offer_sets[]->lander_offer_set_id');
}
}
use Staudenmeir\EloquentJsonRelations\Relations\BelongsToJson;
class Lander extends Model
{
use \Staudenmeir\EloquentHasManyDeep\HasRelationships;
use \Staudenmeir\EloquentJsonRelations\HasJsonRelationships;
public function landerOfferSets(): BelongsToJson
{
return $this->belongsToJson(LanderOfferSet::class, 'lander_offer_sets[]->lander_offer_set_id');
}
LanderFactory
:
'lander_offer_sets' => [
0 => [
'lander_offer_set_id' => (string) LanderOfferSet::factory()->create()->id,
'lander_element_id' => fake()->uuid(),
],
1 => [
'lander_offer_set_id' => (string) LanderOfferSet::factory()->create()->id,
'lander_element_id' => fake()->uuid(),
],
],
LanderOfferSetFactory
:
'offers' => [
0 => [
'offer_id' => (string) Offer::factory()->create()->id,
'redirect_weight' => '40',
'is_active' => false,
],
1 => [
'offer_id' => (string) Offer::factory()->create()->id,
'redirect_weight' => '100',
'is_active' => true,
],
],
landers
table, lander_offer_sets
:
[{"lander_element_id": "88338d96-6c37-3874-a1ca-bf89a216dc2d", "lander_offer_set_id": "1"}, {"lander_element_id": "5b4b897e-62c3-359a-8d75-a53caa612655", "lander_offer_set_id": "2"}]
All relationship queries fail since I set up my factories with (string)
casts, if I remove it everything works.
Now I know that HasManyJson
uses whereJsonContains
and that it only works with INT, but BelongsToJson
also fails, all relationship counts in my Livewire components show 0
:
TextColumn::make('lander_offer_sets_count')
->counts('landerOfferSets')
->label('# of Offer Sets')
->url(fn (Model $record) => route('lander-offer-sets', ['tableFilters' => ['landers' => ['value' => $record->id]]])),
When I change the values back to "lander_offer_set_id": 2
, both relationships work flawlessly.
What can I do here to make this work reliably throughout my application?
Is there any way to override something and cast all values to int?
Hi @madsem,
Before it was working with string values, but now it's not any longer:
lander_offer_set_id
values have always been strings and that worked with both BelongsToJson
and HasManyJson
relationships?
Hi @madsem,
Before it was working with string values, but now it's not any longer:
lander_offer_set_id
values have always been strings and that worked with bothBelongsToJson
andHasManyJson
relationships?
Hey 👋
So, not quite. There used to be just an "offer" relationship, I am rewriting this atm.
But it used to be the exact same type of relationship, like i said: When I change the Factories to integer model FKs, everything starts working.
Currently Im thinking the only way to make it future proof, would be to hook into thr Models booted method and cast values to int.
But it would be great if this could be solved differently? :)
Ps: Before I was using only the BelongsToJson, which was working. But now, it's not
I haven't tested any solutions so I can't recommend anything. You could also look into custom casts.
Thanks 🙏
Wanted to make sure i'm using it right ;)
The custom casts could work well too! Good idea