Laravel 背包 select_multiple | select2_multple 在 updating/editing 具有一对多关系时中断

Laravel backpack select_multiple | select2_multple breaks while updating/editing with one to many relation

我在使用 BackpackCrudController 更新(目标)模型时遇到了一个奇怪的 bug/issue。

首先让我给你一些关于我的数据库结构和模型的信息。 (我省略了无用的关系和函数)

从我的 composer.json

快速掌握
        "php": "^7.2",
        "backpack/crud": "4.0.*",
        "backpack/logmanager": "^3.0",
        "backpack/pagemanager": "^2.0",
        "backpack/permissionmanager": "^5.0",
        "fideloper/proxy": "^4.0",
        "laravel/framework": "^6.2",
        "laravel/tinker": "^2.0"

食谱table:

        Schema::create('recipes', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title');
            $table->string('slug');
            $table->string('image');
            $table->text('content');
            $table->text('preparation');
            $table->json('ingredients');
            $table->integer( 'goal_id')->unsigned()->nullable();
            $table->integer( 'category_id')->unsigned()->nullable();
            $table->unsignedBigInteger( 'user_id');
            $table->timestamps();
        });

        Schema::table('recipes', function(Blueprint $table) {
            $table->foreign( 'goal_id')->references( 'id')->on('goals');
            $table->foreign( 'category_id')->references( 'id')->on('categories');
            $table->foreign( 'user_id')->references( 'id')->on('users');
        });

目标table:

       Schema::create('goals', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title');
            $table->string('slug');
            $table->string('image');
            $table->text( 'content');
            $table->string('workbook')->nullable();
            $table->tinyInteger('duration')->nullable();
            $table->timestamps();
        });

配方模型:

class Recipe extends Model
{
    use CrudTrait;
    use Sluggable;
    use SluggableScopeHelpers;

    /*
    |--------------------------------------------------------------------------
    | GLOBAL VARIABLES
    |--------------------------------------------------------------------------
    */

    protected $table = 'recipes';
    protected $guarded = ['id'];
    protected $fillable = ['title', 'slug', 'image', 'content', 'preparation', 'ingredients', 'goal_id', 'category_id', 'user_id'];


    /*
    |--------------------------------------------------------------------------
    | RELATIONS
    |--------------------------------------------------------------------------
    */
    public function goal(  ) {
        return $this->belongsTo( Goal::class);
    }
}

目标模型:

class Goal extends Model
{
    use CrudTrait;
    use Sluggable;
    use SluggableScopeHelpers;

    /*
    |--------------------------------------------------------------------------
    | GLOBAL VARIABLES
    |--------------------------------------------------------------------------
    */

    protected $table = 'goals';
    protected $guarded = ['id'];
    protected $fillable = ['title', 'slug', 'image', 'content', 'workbook', 'duration'];


    /*
    |--------------------------------------------------------------------------
    | RELATIONS
    |--------------------------------------------------------------------------
    */
    public function recipes(  ) {
        return $this->hasMany( Recipe::class,'goal_id', 'id');
    }
}

更新目标时存在问题,所以这是我的 GoalCrudController:

class GoalCrudController extends CrudController
{
    use \Backpack\CRUD\app\Http\Controllers\Operations\ListOperation;
    use \Backpack\CRUD\app\Http\Controllers\Operations\CreateOperation;
    use \Backpack\CRUD\app\Http\Controllers\Operations\UpdateOperation;
    use \Backpack\CRUD\app\Http\Controllers\Operations\DeleteOperation;
    use \Backpack\CRUD\app\Http\Controllers\Operations\ShowOperation;

    public function setup()
    {
        $this->crud->setModel('App\Models\Goal');
        $this->crud->setRoute(config('backpack.base.route_prefix') . '/goal');
        $this->crud->setEntityNameStrings('goal', 'goals');
    }

    protected function setupCreateOperation()
    {
        $this->crud->setValidation(GoalRequest::class);
        $this->crud->addField([
            'label'     => 'Articles',
            'type'      => 'select2_multiple',
            'name'      => 'articles',
            'entity'    => 'articles',
            'attribute' => 'title',
        ]);
        $this->crud->addField([
            'label'     => 'Recipes',
            'type'      => 'select2_multiple',
            'name'      => 'recipes',
            'entity'    => 'recipes',
            'attribute' => 'title',
        ]);
    }

    protected function setupUpdateOperation()
    {
        $this->setupCreateOperation();
        $this->crud->removeField('image');
        $this->crud->addField([
            'name'      => 'image',
            'label'     => 'Image',
            'type'      => 'image',
            'upload'    => true,
            'prefix'    => 'uploads/',
        ])->afterField('title');
    }
}

同样,我遗漏了不适用于此问题的功能。

现在,问题是当我创建一个目标时,我可以附加一个方法(来自 select2_multiple 字段)并且将创建目标和方法之间的关系。 虽然,当我想 edit/update 我刚刚创建的目标时,例如添加一个新食谱,我得到以下异常:

Exception
Property [recipes] does not exist on this collection instance.

我已尝试将 setupUpdateOperation() 中的字段编辑为以下内容:

        $this->crud->removeField('recipes');
        $this->crud->addField([
            'label'     => 'Recipes',
            'type'      => 'select2_multiple',
            'name'      => 'recipes',
            'entity'    => 'recipes',
            'attribute' => 'title',
            'value'     => Recipe::where('goal_id', $this->crud->getCurrentEntryId()), // <-- added this
        ]);

但随后我得到以下异常:

Call to a member function pluck() on string (View: /Users/name/Docker/sitename/vendor/backpack/crud/src/resources/views/crud/fields/select_multiple.blade.php) // <-- at line 27

我现在的问题实际上是:

如果我需要提供更多信息,请告诉我,我很乐意为您提供。提前致谢!

PS。使用 select_multiple.

时问题相同

经过一番摸索,我终于找到了解决办法。

setupUpdateOperation 函数中,我添加了以下内容:

$this->crud->removeField('recipes'); // remove the original field
$this->crud->addField([
            'label'     => 'Recipes',
            'type'      => 'select2_multiple',
            'name'      => 'recipes',
            'entity'    => 'recipes',
            'attribute' => 'title',
            'value'     => $this->crud->getCurrentEntry()->recipes,
        ]);

有了这个,我设法在更新视图中获取了当前相关的食谱,并实际更新了相关的食谱。