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
我现在的问题实际上是:
- 我怎样才能让用户更新现有目标以添加新目标
食谱?
- 此外,它怎么可能在创建时起作用,但在我创建时却不起作用
想要更新?
- 我在用select_multiple | select2_multiple 这种情况不正确?
- 我的关系不对吗?
- 我这样无法保存关系吗?我需要从食谱结尾开始吗?
- 我应该为更新操作使用不同的 select 字段还是
model_function?
如果我需要提供更多信息,请告诉我,我很乐意为您提供。提前致谢!
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,
]);
有了这个,我设法在更新视图中获取了当前相关的食谱,并实际更新了相关的食谱。
我在使用 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
我现在的问题实际上是:
- 我怎样才能让用户更新现有目标以添加新目标 食谱?
- 此外,它怎么可能在创建时起作用,但在我创建时却不起作用 想要更新?
- 我在用select_multiple | select2_multiple 这种情况不正确?
- 我的关系不对吗?
- 我这样无法保存关系吗?我需要从食谱结尾开始吗?
- 我应该为更新操作使用不同的 select 字段还是 model_function?
如果我需要提供更多信息,请告诉我,我很乐意为您提供。提前致谢!
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,
]);
有了这个,我设法在更新视图中获取了当前相关的食谱,并实际更新了相关的食谱。