I want to use the values of attributes on a model's relationship with Form::label
and Form::text
. The Form
helper was removed from Laravel, so I use 'Form' => 'Collective\Html\FormFacade'
instead.
Here is the relationship in the Order
Model:
<?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');
}
}
And here's the Blade template with Form
. The text in the account_number
<td>
will show:
{"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>
But I want to show inputs for each account_number
attribute separately, not as a JSON string.
I have tried with:
<tr>
<td>{!! Form::label('account_number.id', 'account_number: ') !!}</td>
<td>{!! Form::text('account_number.id')!!}</td>
</tr>
or
<tr>
<td>{!! Form::label('account_number->id', 'account_number: ') !!}</td>
<td>{!! Form::text('account_number->id')!!}</td>
</tr>
or
<tr>
<td>{!! Form::label('account_number', 'account_number: ') !!}</td>
<td>{!! Form::text('account_number["id"]')!!}</td>
</tr>
...but none of these work. They all leave this <td>
empty.
To create input controls for a model's relationships using the FormBuilder
tools provided by Laravel Collective, use the following syntax:
{!! Form::model($order, ...) !!}
...
{!! Form::label('account_number[id]', 'account number: ') !!}
{!! Form::text('account_number[id]') !!}
...
{!! Form::close() !!}
Note the lack of quotation marks around id
. The example in the question contains quotes around the related model's id
attribute, which breaks this magic. The code above renders the following input element using the value of the id
attribute on the Order
model's account_number
relationship:
<input name="account_number[id]" type="text" value="4">
The format shown in the input element's name
attribute enables PHP to parse the POST data as an array. We can fetch the value submitted to a controller method like in this example:
public function save(Request $request)
{
$accountNumber = $request->get('account_number');
echo $accountNumber['id']; // '4'
...
}
This feature is important—FormBuilder
generates input elements designed to work with PHP's automatic grouping of request data into arrays. If we submit multiple input elements on a form for a model's relationship, Laravel makes it easy to save the result:
public function update(Request $request, $orderId)
{
Order::with('account_number')->find($orderId)
->fill($request->all())
->account_number->fill($request->account_number)
->push();
}
Let's do something more in-depth understanding.
While generating a text input element, FormBuilder will look for the value in the session for the value in the old input data then it'll look in the model instance if one is set. Otherwise it'll just use empty.
Before it gets the appropriate value, it will transform the key which we specified, such as account_number.id
, account_number->id
, account_number["id"]
. Focus on the transformKey function
protected function transformKey($key)
{
return str_replace(['.', '[]', '[', ']'], ['_', '', '.', ''], $key);
}
Let's call it with the keys you specified one by one:
account_number.id
=> account_number_id
account_number->id
=> account_number->id
account_number["id"]
=> account_number."id"
Then it will split the key by .
return a array $keys
. And check if exists nested model with $keys[0]
, otherwise return the value of master model with transformed key. getFormValue()
No matter it exists nested model or not, it will get the value through data_get() function.
Obviously, the first key and the second you specified doesn't work. The third one account_number."id"
, it will find the nested model successfully but it won't retrieve the attribute through the way $nestedModel->{"id"}
. Use account_number[id]
instead, it works well.
<td>{!! Form::text('account_number[id]')!!}</td>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With