我试图弄清楚我应该在一个简单的1-n关系字段中做错了什么。
我有一个具有多个“网站”的模型“客户”
在我的客户模型中:
<?php
namespace App\Models;
use Backpack\CRUD\app\Models\Traits\CrudTrait;
use Cviebrock\EloquentSluggable\Sluggable;
use Illuminate\Database\Eloquent\Model;
class Client extends Model
{
use CrudTrait;
use Sluggable;
/*
|--------------------------------------------------------------------------
| GLOBAL VARIABLES
|--------------------------------------------------------------------------
*/
protected $table = 'clients';
// protected $primaryKey = 'id';
// public $timestamps = false;
protected $guarded = ['id'];
// protected $fillable = [];
// protected $hidden = [];
// protected $dates = [];
/*
|--------------------------------------------------------------------------
| FUNCTIONS
|--------------------------------------------------------------------------
*/
/*
|--------------------------------------------------------------------------
| RELATIONS
|--------------------------------------------------------------------------
*/
public function contacts()
{
return $this->belongsToMany(Contact::class);
}
public function websites()
{
return $this->hasMany(Website::class, 'client_id');
}
/*
|--------------------------------------------------------------------------
| SCOPES
|--------------------------------------------------------------------------
*/
/*
|--------------------------------------------------------------------------
| ACCESSORS
|--------------------------------------------------------------------------
*/
/*
|--------------------------------------------------------------------------
| MUTATORS
|--------------------------------------------------------------------------
*/
/**
* Return the sluggable configuration array for this model.
*
* @return array
*/
public function sluggable()
{
return [
'slug' => [
'source' => 'name'
]
];
}
}
我的网站模型
<?php
namespace App\Models;
use Backpack\CRUD\app\Models\Traits\CrudTrait;
use Illuminate\Database\Eloquent\Model;
use Cviebrock\EloquentSluggable\Sluggable;
class Website extends Model
{
use CrudTrait;
use Sluggable;
/*
|--------------------------------------------------------------------------
| GLOBAL VARIABLES
|--------------------------------------------------------------------------
*/
protected $table = 'websites';
// protected $primaryKey = 'id';
// public $timestamps = false;
protected $guarded = ['id'];
// protected $fillable = [];
// protected $hidden = [];
// protected $dates = [];
/*
|--------------------------------------------------------------------------
| FUNCTIONS
|--------------------------------------------------------------------------
*/
/*
|--------------------------------------------------------------------------
| RELATIONS
|--------------------------------------------------------------------------
*/
public function client(){
return $this->belongsTo('App\Models\Client');
}
/*
|--------------------------------------------------------------------------
| SCOPES
|--------------------------------------------------------------------------
*/
/*
|--------------------------------------------------------------------------
| ACCESSORS
|--------------------------------------------------------------------------
*/
/*
|--------------------------------------------------------------------------
| MUTATORS
|--------------------------------------------------------------------------
*/
/**
* Return the sluggable configuration array for this model.
*
* @return array
*/
public function sluggable()
{
return [
'slug' => [
'source' => 'name'
]
];
}
}
在我的客户CRUD控制器中:
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Requests\ClientRequest;
use App\Models\Client;
use App\Models\Contact;
use App\Models\Website;
use Backpack\CRUD\app\Http\Controllers\CrudController;
use Backpack\CRUD\app\Library\CrudPanel\CrudPanelFacade as CRUD;
/**
* Class ClientCrudController
* @package App\Http\Controllers\Admin
* @property-read \Backpack\CRUD\app\Library\CrudPanel\CrudPanel $crud
*/
class ClientCrudController 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;
use \Backpack\CRUD\app\Http\Controllers\Operations\FetchOperation;
public function setup()
{
$this->crud->setModel('App\Models\Client');
$this->crud->with('websites');
$this->crud->setRoute(config('backpack.base.route_prefix') . '/client');
$this->crud->setEntityNameStrings('client', 'clients');
}
protected function setupListOperation()
{
// TODO: remove setFromDb() and manually define Columns, maybe Filters
// $this->crud->setFromDb();
$this->crud->setColumns(['name', 'slug']);
}
protected function setupCreateOperation()
{
$this->crud->setValidation(ClientRequest::class);
// TODO: remove setFromDb() and manually define Fields
// $this->crud->setFromDb();
$this->crud->addFields(
[
[
'name' => 'name',
'type' => 'text',
'label' => "Client name",
'tab' => 'Client info',
],
[ // Checkbox
'name' => 'is_active',
'label' => 'Active',
'type' => 'checkbox',
'tab' => 'Client info',
],
[
'name' => 'description',
'label' => 'Description',
'type' => 'summernote',
'options' => [
'height' => 300,
], // easily pass parameters to the summernote JS initialization
'tab' => 'Client info',
],
[
'name' => 'address',
'label' => 'Address',
'type' => 'address_algolia',
'tab' => 'Client info',
// optional
'store_as_json' => true
],
[
'type' => 'relationship',
'name' => 'contacts', // the method on your model that defines the relationship
'tab' => 'Client info',
// OPTIONALS:
'label' => "Client Contacts",
'attribute' => "full_name", // foreign key attribute that is shown to user (identifiable attribute)
'entity' => 'contacts', // the method that defines the relationship in your Model
'model' => "App\Models\Contact", // foreign key Eloquent model
'placeholder' => "Add a contact", // placeholder for the select2 input
'ajax' => true,
'inline_create' => [
'entity' => 'contact', // you need to specify the entity in singular
'modal_class' => 'modal-dialog modal-xl', // use modal-sm, modal-lg to change width
]
],
[
'type' => "relationship",
'name' => 'websites', // the method on your model that defines the relationship
'tab' => 'Assets',
// // OPTIONALS:
// 'label' => "Client Websites",
// 'attribute' => "name", // foreign key attribute that is shown to user (identifiable attribute)
// 'entity' => 'websites', // the method that defines the relationship in your Model
// 'model' => \App\Models\Website::class, // foreign key Eloquent model
// 'placeholder' => "Select websites", // placeholder for the select2 input
// 'ajax' => true,
// 'pivot' => false,
// 'inline_create' => [
// 'entity' => 'website',
// 'modal_class' => 'modal-dialog modal-xl', // use modal-sm, modal-lg to change width
// ] // you need to specify the entity in singular
]
]
);
}
protected function setupUpdateOperation()
{
$this->setupCreateOperation();
}
public function fetchWebsites()
{
return $this->fetch(\App\Models\Website::class);
}
public function fetchContacts()
{
// return $this->fetch(\App\Models\Contact::class);
return $this->fetch([
'model' => \App\Models\Contact::class, // required
'searchable_attributes' => ['first_name', 'last_name', 'description'],
'query' => function($model) {
return $model->where('is_active', 1);
} // to filter the results that are returned
]);
}
}
现在,当我取消注释“ inline_create”部分时,我可以成功显示CRUD,搜索已经创建的“网站”,并添加“网站”。
但是,当我选择先前创建的“网站”后尝试保存时,出现查询异常:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'websites' in 'field list' (SQL: update `clients` set `websites` = ["1"], `clients`.`updated_at` = 2020-06-04 15:52:49 where `id` = 1)
此“ relationship”字段是否应使用client_id更新网站模型,而不更新Clients模型?还是我对1-n关系在这里的工作方式有基本的误解...
我在做什么错?
只是背包的新手我有一些类似的问题。DB是:客户有很多地址(1-n)当我编辑客户时,可以编辑多个地址。 (添加/编辑/删除)
受此问题启发:https://github.com/Laravel-Backpack/CRUD/issues/2729
仅供参考:我的显示方法和解决方案:ListEntries in table for relationship on show page - backpack for laravel
我已经在我的客户模型中创建了一个可变器
public function setAddressesAttribute($value) {
$data = (json_decode($value, true)); //converts json into array
$keys = self::addresses()->get()->modelKeys();
//Insertar o actualizar registros en parent
if(is_array($data)) {
foreach ($data as $entry) {
if (!empty($entry['address1'])) {
$id = (int) $entry['id'];
unset($entry['id']);
if (($key = array_search($id, $keys)) !== false)
unset($keys[$key]);
self::addresses()->updateOrCreate(['id' => $id], $entry);
}
}
}
//Eliminar registros en parent
if(!empty($keys)) {
foreach ($keys as $id)
self::addresses()->find($id)->delete();
}
}
以及在我的CustomerCrudController中,在setupCreateOperation方法中,我添加了那些字段:
'addresses'=>[
//...
[
'name' => 'id',
'type' => 'hidden',
],
[
'name' => 'user_id',
'type' => 'hidden',
'default' => CRUD::getCurrentEntryId(),
],
//...
]
因此,在您的情况下,您必须在Client模型上创建一个方法:
public function setWebsitesAttribute($value) {
$data = (json_decode($value, true)); //converts json into array
$keys = self::websites()->get()->modelKeys();
//Insertar o actualizar registros en parent
if(is_array($data)) {
foreach ($data as $entry) {
if (!empty($entry['address1'])) {
$id = (int) $entry['id'];
unset($entry['id']);
if (($key = array_search($id, $keys)) !== false)
unset($keys[$key]);
self::websites()->updateOrCreate(['id' => $id], $entry);
}
}
}
//Eliminar registros en parent
if(!empty($keys)) {
foreach ($keys as $id)
self::websites()->find($id)->delete();
}
}
在您的网站模型中,您必须正确填写数组:
protected $fillable = [];
希望这对您有帮助。