緣由
最近在使用Laravel-Admin後臺進行開發時,發現了框架的一個Bug。那就是編輯的時候無法回顯。然後偶然的機會,我將駝峰和下劃線都寫上了,最後震驚了。
下劃線有值,駝峰的反而沒值????emmmmmm
直接使用下劃線而不用駝峰就沒值,真是頭疼呢?
/**
* Make a form builder.
*
* @return Form
*/
protected function form()
{
$form = new Form(new Students);
$form->text('classInfo.grade', '年級');
$form->text('class_info.grade', '年級');
$form->text('classInfo.class', '班級');
$form->text('class_info.class', '班級');
return $form;
}
classInfo模型
class ClassInfo extends Model
{
protected $table = 'class_info';
protected $fillable = ['grade', 'class'];
public function students()
{
return $this->belongsTo(Students::class);
}
}
students模型
class Students extends Model
{
protected $table = 'students';
public function contacts()
{
return $this->hasMany(Contacts::class, 'student_id');
}
public function classInfo()
{
return $this->hasOne(ClassInfo::class, 'student_id');
}
}
無奈
只能是自己Debug了,因為找了很多文章也沒解決方案,專案issue也沒有一對一模型出錯的文章。我就奇怪了,為什麼這麼常用的功能有Bug呢?還是隻是我在用而已(逃)
首先思路要清晰,畢竟要找問題究竟出在哪裡。因為是我是用form元件的text方法,首先就會想到是form排查。所以我找到了src/Form.php
這個檔案。
在使用Laravel-Admin命令生成的控制器會帶上一個修改函式
/**
* Edit interface.
*
* @param mixed $id
* @param Content $content
* @return Content
*/
public function edit($id, Content $content)
{
return $content
->header('Edit')
->description('description')
->body($this->form()->edit($id));
}
然後我們會看見$this->form()
這個函式不就是我們編寫欄位的函式嗎?然後呼叫了edit
函式
/**
* Generate a edit form.
*
* @param $id
*
* @return $this
*/
public function edit($id)
{
$this->builder->setMode(Builder::MODE_EDIT);
$this->builder->setResourceId($id);
$this->setFieldValue($id);
return $this;
}
這個函式會設定編輯模式,然後設定資源id
這些其實都不是我們要管的。畢竟我們是value
值沒有.那麼當我看見setFieldValue
函式後就突然興奮,這不就是設定input
輸入框的value
值嗎?
/**
* Set all fields value in form.
*
* @param $id
*
* @return void
*/
protected function setFieldValue($id)
{
$relations = $this->getRelations();
$builder = $this->model();
if ($this->isSoftDeletes) {
$builder = $builder->withTrashed();
}
$this->model = $builder->with($relations)->findOrFail($id);
$this->callEditing();
// static::doNotSnakeAttributes($this->model);
$data = $this->model->toArray();
$this->builder->fields()->each(function (Field $field) use ($data) {
if (!in_array($field->column(), $this->ignored)) {
$field->fill($data);
}
});
}
這裡面要關注的點還有就是獲取依賴的
getRelations
函式,這個函式其實就是上面模型的函式名稱。所以我們的$relations=['classInfo, contacts']
。
重點來了,我們將$data
列印出來看看
array:13 [▼
"id" => 5
"name" => "s1"
"gender" => 0
"enrol" => 2019
"birth" => "2019-04-22"
"address" => "test"
"avatar" => null
"status" => 0
"desc" => "test"
"created_at" => "2019-04-22 15:42:20"
"updated_at" => "2019-04-22 15:42:20"
"class_info" => array:7 [▼
"id" => 1
"student_id" => 5
"grade" => "1"
"director" => null
"class" => "2"
"created_at" => "2019-04-22 15:42:20"
"updated_at" => "2019-05-20 14:37:40"
]
"contacts" => array:2 [▶]
]
emmmmm,依賴傳進去後得到的資料竟然是以表名來做鍵的呀。
結論
這是因為駝峰和下劃線的問題。我在資料庫使用下劃線class_info
,然後我的form
函式裡面寫的是
$form->text('classInfo.grade', '年級');
$form->text('classInfo.class', '班級');
然後這個是對應在模型中的函式名的,然後在field->fill
填充$data
資料進去賦值時,就會發現找不到classInfo
,只有class_info
。然後這裡的解決方案有兩種:
- 直接將模型函式使用下劃線,不用駝峰,那麼資料欄位就對得上了
- 新增程式碼,將data變數填充
classInfo
變數進來foreach ($this->model->getRelations() as $k => $v) { if ($v instanceof Model && isset($data[$v->getTable()])) { $data[$k] = $data[$v->getTable()]; } }
以上就是我的Debug思路,可能解決方案有點差,歡迎提出更好的方案一起交流~