如何在Laravel Form Facade中使用关系值?

Kri*_*ofe 7 php forms laravel laravel-5 laravel-eloquent

我想在模型与Form::label和的关系中使用属性值Form::text.该Form助手从Laravel取出,所以我用'Form' => 'Collective\Html\FormFacade'代替.

以下是Order模型中的关系:

<?php namespace App\Models;

use Illuminate\Database\Eloquent\SoftDeletes;

class Order extends \Eloquent
{
    use SoftDeletes;

    public function account_number()
    {
        return $this->belongsTo('\App\Models\Account_number', 'product_id', 'id');
    }
}
Run Code Online (Sandbox Code Playgroud)

这是Blade模板Form.account_number <td>将显示的文字:

{"id":4,"user_id":52,"account_type":"alipay","account_no":"xxxxxx","account_name":"xxxxxx","phone":"xxxxxx","created_at":"2017-11-15 14:43:51","updated_at":"2017-11-15 14:43:51","deleted_at":null}
Run Code Online (Sandbox Code Playgroud)
{!! Form::model($order, array('files' => true)) !!}
<table border="1">
<tr>
  <td>{!! Form::label('out_trade_no', 'out_trade_no: ') !!}</td>
  <td>{!! Form::text('out_trade_no')!!}</td>
</tr>
<tr>
  <td>{!! Form::label('account_number', 'account_number: ') !!}</td>
  <td>{!! Form::text('account_number')!!}</td>
</tr>
</table>
Run Code Online (Sandbox Code Playgroud)

但我想分别显示每个account_number属性的输入,而不是JSON字符串.

我尝试过:

<tr>
  <td>{!! Form::label('account_number.id', 'account_number: ') !!}</td>
  <td>{!! Form::text('account_number.id')!!}</td>
</tr>
Run Code Online (Sandbox Code Playgroud)

要么

<tr>
  <td>{!! Form::label('account_number->id', 'account_number: ') !!}</td>
  <td>{!! Form::text('account_number->id')!!}</td>
</tr>
Run Code Online (Sandbox Code Playgroud)

要么

<tr>
  <td>{!! Form::label('account_number', 'account_number: ') !!}</td>
  <td>{!! Form::text('account_number["id"]')!!}</td>
</tr>
Run Code Online (Sandbox Code Playgroud)

......但这些都不起作用.他们都把这个<td>留空.

Cy *_*nol 5

要使用Laravel Collective提供的FormBuilder工具为模型关系创建输入控件,请使用以下语法:

{!! Form::model($order, ...) !!} 
    ...
    {!! Form::label('account_number[id]', 'account number: ') !!}
    {!! Form::text('account_number[id]') !!}
    ...
{!! Form::close() !!}
Run Code Online (Sandbox Code Playgroud)

请注意 周围缺少引号id。问题中的示例包含相关模型id属性的引号,这打破了这种魔力。上面的代码使用模型关系id上的属性值呈现以下输入元素:Orderaccount_number

<input name="account_number[id]" type="text" value="4">
Run Code Online (Sandbox Code Playgroud)

输入元素属性中显示的格式name使 PHP 能够将 POST 数据解析为数组。我们可以获取提交给控制器方法的值,如下例所示:

public function save(Request $request) 
{
    $accountNumber = $request->get('account_number'); 

    echo $accountNumber['id']; // '4'
    ...
}
Run Code Online (Sandbox Code Playgroud)

此功能很重要 —FormBuilder生成旨在与 PHP 将请求数据自动分组到数组中配合使用的输入元素。如果我们在表单上提交多个输入元素以获取模型关系,Laravel 可以轻松保存结果:

public function update(Request $request, $orderId) 
{
    Order::with('account_number')->find($orderId)
        ->fill($request->all())
        ->account_number->fill($request->account_number)
        ->push();
}
Run Code Online (Sandbox Code Playgroud)


Con*_*hen 2

让我们做一些更深入的了解。

在生成文本输入元素时,FormBuilder将在会话中查找旧输入数据中的值,然后在模型实例中查找(如果已设置)。否则它只会使用空。
在获得合适的值之前,它会转换我们指定的键,例如account_number.id, account_number->id, account_number["id"]。重点关注transformKey函数

protected function transformKey($key)
{
    return str_replace(['.', '[]', '[', ']'], ['_', '', '.', ''], $key);
}
Run Code Online (Sandbox Code Playgroud)

让我们用您指定的键一一调用它:

  1. account_number.id =>account_number_id
  2. account_number->id =>account_number->id
  3. account_number["id"]=>account_number."id"

.然后它将通过返回一个数组来分割密钥$keys。并检查是否存在嵌套模型$keys[0],否则返回带有转换后的键的主模型的值。获取表单值()

无论是否存在嵌套模型,都会通过data_get()函数获取值。

显然,您指定的第一个键和第二个键不起作用。第三种account_number."id",它会成功找到嵌套模型,但不会通过该方式检索属性$nestedModel->{"id"}。代替使用account_number[id],效果很好。

<td>{!! Form::text('account_number[id]')!!}</td>
Run Code Online (Sandbox Code Playgroud)