Skip to content

Instantly share code, notes, and snippets.

@pxpm
Created October 8, 2021 22:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pxpm/d7709df4e1fac04c0c329a2ad0b35a5b to your computer and use it in GitHub Desktop.
Save pxpm/d7709df4e1fac04c0c329a2ad0b35a5b to your computer and use it in GitHub Desktop.
Backpack 4.1 morphMany relation
<?php
namespace App\Http\Controllers;
use Backpack\CRUD\app\Http\Controllers\CrudController;
use Backpack\CRUD\app\Library\CrudPanel\CrudPanelFacade as CRUD;
class ArticleCrudController extends CrudController
{
use \Backpack\CRUD\app\Http\Controllers\Operations\ListOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\CreateOperation { store as traitStore; } //IMPORTANT HERE
use \Backpack\CRUD\app\Http\Controllers\Operations\UpdateOperation { update as traitUpdate; } //IMPORTANT HERE
use \Backpack\CRUD\app\Http\Controllers\Operations\DeleteOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\ShowOperation;
public function setup()
{
CRUD::setModel(\App\Models\Article::class);
CRUD::setRoute(config('backpack.base.route_prefix') . '/article');
CRUD::setEntityNameStrings('article', 'articles');
}
protected function setupListOperation()
{
CRUD::column('title');
}
protected function setupCreateOperation()
{
CRUD::field('title');
CRUD::field('comments_field')
->type('repeatable')
->fields([
[
'name' => 'id',
'type' => 'hidden',
],
[
'name' => 'comment_text',
'type' => 'text'
]])
]);
}
protected function setupUpdateOperation()
{
$this->setupCreateOperation();
}
protected function setupShowOperation()
{
CRUD::column('title');
}
public function store()
{
$comments = json_decode(request('comments_list'), true);
$response = $this->traitStore();
$this->crud->entry->comments()->createMany($comments);
return $response;
};
public function update()
{
$comments = collect(json_decode(request('comments_list'), true));
$response = $this->traitUpdate();
$created_comments_ids = [];
$comments->each(function($item, $key) use (&$created_comments_ids) {
if ($item['id']) {
$this->crud->entry->comments()->updateOrCreate(['id' => $item['id']], $item);
} else {
$created_comments_ids[] = $this->crud->entry->comments()->create($item)->id;
}
});
$related_comments_in_request = collect(array_merge($comments->where('id', '!=', '')->pluck('id')->toArray(), $created_comments_id));
$related_comments_in_db = $this->crud->entry->comments;
$related_comments_in_db->each(function($item, $key) use ($related_comments_in_request) {
if (!$related_comments_in_request->contains($item['id'])) {
$item->delete();
}
});
return $response;
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Article extends Model
{
use \Backpack\CRUD\app\Models\Traits\CrudTrait;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'title',
];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'id' => 'integer',
];
public function comments()
{
return $this->morphMany(\App\Models\Comment::class, 'commentable');
}
//acessor to get the video populated in the repeatable field again
public function getVideoFieldAttribute() {
return json_encode($this->comments->map(function($comment) {
return ['comment_text' => $comment->comment_text];
}));
}
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
use \Backpack\CRUD\app\Models\Traits\CrudTrait;
protected $fillable = ['comment_text'];
/**
* Get the parent commentable model (article or post).
*/
public function commentable()
{
return $this->morphTo();
}
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use \Backpack\CRUD\app\Models\Traits\CrudTrait;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'title',
];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'id' => 'integer',
];
public function comments()
{
return $this->morphMany(\App\Models\Comment::class, 'commentable');
}
//acessor to get the video populated in the repeatable field again
public function getCommentsListAttribute() {
return json_encode($this->comments->map(function($comment) {
return ['comment_text' => $comment->comment_text];
}));
}
}
@tabacitu
Copy link

.php extension to filenames please? 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment