CRUD: [4.1] Relationship field does not work inside repeatable
I’ve managed to get it to work in part using the Repeatable Relationship field. With the following attribute: ‘multiple’ => false, ‘data_source’ => url($this->crud->route.‘/fetch/person’),
I can add the data or register a new one in the table.
//RELATIVE
$this->crud->addField([
'name' => 'relation_relative',
'label' => trans('contact.relative.data'),
'type' => 'repeatable',
'tab' => trans('contact.relative.tab'),
'fields' => [
[ 'name' => 'id',
'type' => 'hidden',
],
[ 'name' => 'contact_id',
'type' => 'hidden',
'default' => $this->crud->getCurrentEntryId(),
],
[
'name' => 'data1',
'label' => trans('contact.relative.name'),
'type' => 'relationship',
'wrapper' => ['class' => 'form-group col-md-8'],
'entity' => 'relatives.person',
'data_source' => url($this->crud->route.'/fetch/person'),
'attribute' => 'display_name',
'model' => 'App\Models\ContactPerson',
'ajax' => false,
'multiple' => false,
'allows_null' => true,
'inline_create' => ['entity' => 'contactperson'],
],
[ 'name' => 'data2',
'label' => trans('contact.relative.type'),
'type' => 'select_from_array',
'wrapper' => ['class' => 'form-group col-md-4'],
'options' => ContentType::getTypeRelationRelatives(),
],
[ 'name' => 'data3',
'label' => trans('contact.relative.label'),
'type' => 'text',
],
],
]);
public function fetchPerson()
{ return $this->fetch('App\Models\ContactPerson'); }

The problem I have is that after saving and re-modifying, it doesn’t associate the value in the Relationship field.

Well if you know how to solve that part then it would be repeatable.
I share the way I found to intercept in the model and save in the related table. And the way to read it and convert to json. This can be added to the documentation.
class ContactFamily extends Model
{
protected $table = 'contacts';
public $timestamps = true;
protected $guarded = ['id'];
protected $fillable = ['display_name', 'civil_status', 'status',
'relation_parent', 'relation_spouse', 'relation_children', 'relation_relative', 'relation_other'];
public function relatives()
{
$keys = array_keys(ContentType::getTypeRelationRelatives());
return $this->hasMany('App\Models\ContactRelation','contact_id', 'id')
->whereIn('data2', $keys);
}
public function getRelationRelativeAttribute() {
$data = self::relatives()->get();
return $data->toJson();
}
public function setRelationRelativeAttribute($value) {
$data = (json_decode($value, true)); //converts json into array
$keys = self::relatives()->get()->modelKeys();
//Insertar o actualizar registros en parent
if(is_array($data)) {
foreach ($data as $entry) {
if (!empty($entry['data1'])) {
$id = (int) $entry['id'];
unset($entry['id']);
if (($key = array_search($id, $keys)) !== false)
unset($keys[$key]);
self::relatives()->updateOrCreate(['id' => $id], $entry);
}
}
}
//Eliminar registros en parent
if(!empty($keys)) {
foreach ($keys as $id)
self::relatives()->find($id)->delete();
}
}
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 1
- Comments: 17 (12 by maintainers)
The problem with the Relationship field is resolved. What I did was upgrade the chrome browser from version 79 to 80
If you can verify what I say, it is possible that the Relationship field is not compatible with the following versions: chrome 79 firefox 66 internet explorer 11 Microsoft Edge 41 - EdgeHTML 16
As the PR #2763 is open and I think very close to be merged, let’s move any further conversation about this topic over there.
Thanks again @DanielKimmich , and sorry for making you go to the trouble of fixing this. I am very happy that you found a solution that works for you, but if the one we provided in the PR matches your expectations you could do a
composer updateas soon as the PR gets merged to have the latest code.From my understanding, and what I told to @tabacitu is that
relationshipfield in the context of a repeatable field, is only useful as a shortcut, a way to allow people write less code and have the fields displayed, because in reality we are not directly creating/editing any relation. That can be done after when you intercept the request, but does not matter if it’s a select2_from_ajax or a relationship with ajax, in request you get the selected value.Wish you the best.
Pedro
Hey @tabacitu i did some dig around,
Couldn’t we make the function public instead of protected
https://github.com/Laravel-Backpack/CRUD/blob/400bb8827bb02fc8b6ad2d6502e3710afcb57936/src/app/Library/CrudPanel/Traits/FieldsProtectedMethods.php#L18
And add before the line:
https://github.com/Laravel-Backpack/CRUD/blob/400bb8827bb02fc8b6ad2d6502e3710afcb57936/src/resources/views/crud/fields/repeatable.blade.php#L30
That way we could still write the fields exactly as in
$crud->addField(), and expect the sameguessing.This would also work wonders for relationships, otherwise I think using relationships is a no go in repeatables, because some keys are needed beforehand like
relation_typeetc.Do you see any inconvenience in this ?
Aftermath …
You referenced that repeatable strips the name from fields so I really think that making relationships work here is also an impossiblemazing job, we parse names for html etc, and that only makes sense because we are creating the relations, need validation etc.
In this scenario everything is stored in json, or handled by developer after submission so I think making relationships work here does not make much sense at all. I remember in our conversation we talked about this, and looking at it from some perspective it clearly does not worth the effort.
I think we should focus in making only
fetch_and_creatework in here because of theInlineCreatefeature, for other scenarios you have theselect2, select2_multiple, select2_from_ajax, select2_from_ajax_multiple.Let me know how you think we should tackle this one.
On it 👍