Closed newtongamajr closed 4 years ago
How is your SelectPlus::make()
... configured?
My belongToMany:
public function cities()
{
$db = DB::connection(config('galileosoft.galileo-tenant'))->getDatabaseName();
return $this->belongsToMany(City::class,"$db.microregionscities",'idmicroregions','idcities')
->withTimestamps('created_at','updated_at');
}
My select-plus component call:
SelectPlus::make('Municípios Pertencentes','cities',City::class)
->label('munic_estado')
->usingDetailLabel(function ($models) {
$result= [];
foreach ($models as $model)
{
$city= $model->find($model->idcities);
$uf = $city->state()->first();
$resultado[] = "$city->cityname/$uf->code";
}
return $result;
})
->ajaxSearchable(function ($search) {
return \Galileo\Models\Gll\City::where('cityname','like', "%{$search}%")->limit(5);
}),
I'm using hyn/multitenant package to create a system-tentant environment that's why I'm capturing the dbname from my connection. But this is totally transparent since from tinker I'm not just associated cities to microregions, as it was finely visible from select-plus component after a manual data load!
It looks like you have a tendency to use non-standard names for your primary key names, (typically it is id
). I would check to see what the value of this is: $city = new City; $city->getKeyName()
and make sure it matches what the actual key name is of the model.
This is what fillAttribute() is doing:
https://github.com/ziffmedia/nova-select-plus/blob/master/src/SelectPlus.php#L175-L187
Yes, all my PK are id
This is my MicroRegions model: `<?php
namespace Galileo\Models\Gll;
use DB; use Galileo\Support\Gll\GalileoModel; use Galileo\Traits\Gll\GerarUuid; use Hyn\Tenancy\Traits\UsesTenantConnection;
class MicroRegion extends GalileoModel { use GerarUuid, UsesTenantConnection;
protected $table = 'microregions'; protected $primaryKey = 'idmicroregions'; protected $keyType = 'string'; protected $fillable = [ 'name', 'code' ];
public function cities() { $db = DB::connection(config('galileosoft.galileo-tenant'))->getDatabaseName(); return $this->belongsToMany(City::class,"$db.microregionscities",'idmicroregions','idcities') ->withTimestamps('created_at','updated_at'); } }`
And this is my Cities model: `<?php
namespace Galileo\Models\Gll;
use DB; use Galileo\Support\Gll\GalileoModel; use Galileo\Traits\Gll\GerarUuid; use Hyn\Tenancy\Traits\UsesSystemConnection;
class Cityextends GalileoModel { use GerarUuid, UsesSystemConnection;
protected $table = 'cities'; protected $primaryKey = 'idcities'; protected $keyType = 'string'; protected $fillable = [ 'idpaisesufs', 'cityname', 'cepprincipal', 'codibge', ];
protected $appends = ['munic_estado'];
public function unidfederativa() { return $this->belongsTo(PaisesUF::class, 'idpaisesufs', 'idpaisesufs'); }
public function bairros() { return $this->hasMany(Bairro::class,'idmunicipios','idmunicipios'); }
public function enderecos() { return $this->hasMany(Endereco::class,'idmunicipios', 'idmunicipios'); }
public function microregions() { $db = DB::connection(config('galileosoft.galileo-tenant'))->getDatabaseName(); return $this->belongsToMany(MicroRegion::class,"$db.microregionscities",'idcities','idmicroregions') ->withTimestamps('created_at','updated_at'); } /**
*/ public function getMunicEstadoAttribute() { $uf = $this->unidfederativa()->first(); $nomeMunicipio = mb_convert_encoding($this->nomemunicipio,'UTF-8','UTF-8'); return "{$nomeMunicipio}/{$uf->sigla}"; } public function getCepPrincipalAttribute($cepPrincipal) { return formataCEP($cepPrincipal); }
public function setCepPrincipal($cepPrincipal) { $this->attributes['cepprincipal'] = (int) removeFormatacao($cepPrincipal); }`
I don't think this is specific to UUID's necessarily.
In the exception message you provided, I see this:
insert into `607585c0a06311e9bf656ba9c86393fd`.`microregionscities` (`updated_at`, `created_at`, `idmicroregions`, `idcities`) values (2020-04-20 01:01:25, 2020-04-20 01:01:25, bc06fba0-82a7-11ea-967e-a1507a7c70b6, ))
That seems to indicate that the idcities
's value is missing from the values that are passed back.
If you can, try and see what that POST body is for the update (using the developer tools with the browser) that is sent to the server when you click save on your form that has the Select field in it. What do the keys and values look like for the selected things?
@ralphschindler, just correct me if I misunderstood something, but I was analyzing the code you sent me: ´ protected function fillAttribute(NovaRequest $request, $requestAttribute, $model, $attribute) { // returning a function allows this to run after the model has been saved (which is crucial if this is a new model) return function () use ($request, $requestAttribute, $model, $attribute) { $values = collect(json_decode($request[$requestAttribute], true));
$keyName = $model->getKeyName();
if ($this->reorderable) {
$syncValues = $values->mapWithKeys(function ($value, $index) use ($keyName) {
return [$value[$keyName] => [$this->reorderable => $index + 1]];
});
} else {
$syncValues = $values->pluck($keyName);
}
$model->{$attribute}()->sync($syncValues);
};
}`
From my understanding, $model in this case is MicroRegion::class. When you do ' $keyName = $model->getKeyName(); you're getting the key from Microregion::class, thats 'idmicroregions', when you pluck the values to populate $syncvalues, it will result in a collection of null values. I replicated this situation on Tinker, and obtained the ame error, I've got using 'select-plus'. $keyName should come from related model instead of the origin model.
What do you think?
This is a bug, I've pushed a fix and released 1.0.6. let me know if it works for you...
https://github.com/ziffmedia/nova-select-plus/commit/804ab09926ed3c9d728f6bfa6b94984d95971aaa
Working as a Swiss clock! Thanks for your attention, @ralphschindler and for your great package!
Fixed in v1.0.6
Hi, In my relation table I have both origin model and related model identified by UUIDs.
I'm populating my data from microregions resource and when I do so, idcities always remain empty.
Thanks!