如何在 Laravel Form Facade 中使用关系值?
How to use relationship value in Laravel Form Facade?
我想在模型与 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');
}
}
这里是带有 Form
的 Blade 模板。 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}
{!! 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>
但我想分别显示每个 account_number
属性的输入,而不是 JSON 字符串。
我试过:
<tr>
<td>{!! Form::label('account_number.id', 'account_number: ') !!}</td>
<td>{!! Form::text('account_number.id')!!}</td>
</tr>
或
<tr>
<td>{!! Form::label('account_number->id', 'account_number: ') !!}</td>
<td>{!! Form::text('account_number->id')!!}</td>
</tr>
或
<tr>
<td>{!! Form::label('account_number', 'account_number: ') !!}</td>
<td>{!! Form::text('account_number["id"]')!!}</td>
</tr>
...但是 none 这些工作。他们都把这个 <td>
留空了。
要使用 FormBuilder
tools provided by Laravel Collective 为模型的关系创建输入控件,请使用以下语法:
{!! Form::model($order, ...) !!}
...
{!! Form::label('account_number[id]', 'account number: ') !!}
{!! Form::text('account_number[id]') !!}
...
{!! Form::close() !!}
请注意 id
周围缺少引号。问题中的示例包含相关模型的 id
属性周围的引号,这打破了这种魔力。上面的代码使用 Order
模型的 account_number
关系上的 id
属性值呈现以下输入元素:
<input name="account_number[id]" type="text" value="4">
输入元素的 name
属性中显示的格式使 PHP 能够将 POST 数据解析为数组。我们可以获取提交给控制器方法的值,如本例所示:
public function save(Request $request)
{
$accountNumber = $request->get('account_number');
echo $accountNumber['id']; // '4'
...
}
此功能很重要——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();
}
您使用 LaravelCollective 的带有模型绑定的 FirmBuilder 的方式是错误的。
假设您有以下顺序的数据:
{
id: 1,
....., // some other fields
account_number: {
"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
}
}
所以现在如果你想在文本字段中显示 account_number id
那么你可以这样写你的表单生成器:
{!! Form::model($order, ...) !!}
...
<tr>
<td>{!! Form::label('account_number', 'account number: ') !!}</td>
<td>{!! Form::text('account_number', $order->account_number->id) !!}</td>
</tr>
...
{!! Form::close() !!}
或
<td>{!! Form::text('account_number[id]') !!}</td>
但是在第二个答案中,您会在提交表单时遇到问题。因为除了获得您想要的值之外,该行代码还将您的输入名称属性的值重命名为 account_number[id]
而不是 account_number
。所以最好的选择是使用第一种解决方案。这是 LaravelCollective 中表单模型绑定的 link:https://laravelcollective.com/docs/master/html#form-model-binding
让我们做一些更深入的了解。
在生成文本输入元素时,FormBuilder 将在会话中查找旧输入数据中的值,然后在模型实例中查找是否已设置。否则它只会使用空的。
在它得到合适的值之前,它会转换我们指定的键,比如account_number.id
、account_number->id
、account_number["id"]
。关注transformKey函数
protected function transformKey($key)
{
return str_replace(['.', '[]', '[', ']'], ['_', '', '.', ''], $key);
}
让我们用您指定的键一一调用它:
account_number.id
=> account_number_id
account_number->id
=> account_number->id
account_number["id"]
=> account_number."id"
然后它将密钥拆分为 .
return 数组 $keys
。并检查是否存在 $keys[0]
的嵌套模型,否则 return 具有转换键的主模型的值。 getFormValue()
无论是否存在嵌套模型,都会通过data_get()函数取值
显然,您指定的第一个键和第二个键不起作用。第三个account_number."id"
,它会成功找到嵌套模型,但不会通过$nestedModel->{"id"}
的方式检索属性。使用 account_number[id]
代替,效果很好。
<td>{!! Form::text('account_number[id]')!!}</td>
在尝试自己实施环境后,我的结论-
{!! 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[id]')!!}</td>
</tr>
</table>
我想在模型与 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');
}
}
这里是带有 Form
的 Blade 模板。 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}
{!! 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>
但我想分别显示每个 account_number
属性的输入,而不是 JSON 字符串。
我试过:
<tr>
<td>{!! Form::label('account_number.id', 'account_number: ') !!}</td>
<td>{!! Form::text('account_number.id')!!}</td>
</tr>
或
<tr>
<td>{!! Form::label('account_number->id', 'account_number: ') !!}</td>
<td>{!! Form::text('account_number->id')!!}</td>
</tr>
或
<tr>
<td>{!! Form::label('account_number', 'account_number: ') !!}</td>
<td>{!! Form::text('account_number["id"]')!!}</td>
</tr>
...但是 none 这些工作。他们都把这个 <td>
留空了。
要使用 FormBuilder
tools provided by Laravel Collective 为模型的关系创建输入控件,请使用以下语法:
{!! Form::model($order, ...) !!}
...
{!! Form::label('account_number[id]', 'account number: ') !!}
{!! Form::text('account_number[id]') !!}
...
{!! Form::close() !!}
请注意 id
周围缺少引号。问题中的示例包含相关模型的 id
属性周围的引号,这打破了这种魔力。上面的代码使用 Order
模型的 account_number
关系上的 id
属性值呈现以下输入元素:
<input name="account_number[id]" type="text" value="4">
输入元素的 name
属性中显示的格式使 PHP 能够将 POST 数据解析为数组。我们可以获取提交给控制器方法的值,如本例所示:
public function save(Request $request)
{
$accountNumber = $request->get('account_number');
echo $accountNumber['id']; // '4'
...
}
此功能很重要——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();
}
您使用 LaravelCollective 的带有模型绑定的 FirmBuilder 的方式是错误的。 假设您有以下顺序的数据:
{
id: 1,
....., // some other fields
account_number: {
"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
}
}
所以现在如果你想在文本字段中显示 account_number id
那么你可以这样写你的表单生成器:
{!! Form::model($order, ...) !!}
...
<tr>
<td>{!! Form::label('account_number', 'account number: ') !!}</td>
<td>{!! Form::text('account_number', $order->account_number->id) !!}</td>
</tr>
...
{!! Form::close() !!}
或
<td>{!! Form::text('account_number[id]') !!}</td>
但是在第二个答案中,您会在提交表单时遇到问题。因为除了获得您想要的值之外,该行代码还将您的输入名称属性的值重命名为 account_number[id]
而不是 account_number
。所以最好的选择是使用第一种解决方案。这是 LaravelCollective 中表单模型绑定的 link:https://laravelcollective.com/docs/master/html#form-model-binding
让我们做一些更深入的了解。
在生成文本输入元素时,FormBuilder 将在会话中查找旧输入数据中的值,然后在模型实例中查找是否已设置。否则它只会使用空的。
在它得到合适的值之前,它会转换我们指定的键,比如account_number.id
、account_number->id
、account_number["id"]
。关注transformKey函数
protected function transformKey($key)
{
return str_replace(['.', '[]', '[', ']'], ['_', '', '.', ''], $key);
}
让我们用您指定的键一一调用它:
account_number.id
=>account_number_id
account_number->id
=>account_number->id
account_number["id"]
=>account_number."id"
然后它将密钥拆分为 .
return 数组 $keys
。并检查是否存在 $keys[0]
的嵌套模型,否则 return 具有转换键的主模型的值。 getFormValue()
无论是否存在嵌套模型,都会通过data_get()函数取值
显然,您指定的第一个键和第二个键不起作用。第三个account_number."id"
,它会成功找到嵌套模型,但不会通过$nestedModel->{"id"}
的方式检索属性。使用 account_number[id]
代替,效果很好。
<td>{!! Form::text('account_number[id]')!!}</td>
在尝试自己实施环境后,我的结论-
{!! 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[id]')!!}</td>
</tr>
</table>