How to use relationship value in Laravel Form Facade?

I want to use attribute values ​​to model relationship with Form::label and Form::text . The Form Helper has been removed from Laravel, so I use 'Form' => 'Collective\Html\FormFacade' .

Here is the relation 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 is the Blade template with Form . The text in 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 the inputs for each account_number attribute separately, and not as a JSON string.

I 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 not one of these works. They all leave this <td> empty.

+7
php forms laravel laravel-5 laravel-eloquent
source share
4 answers

Do something deeper understanding.

When creating a text input element, FormBuilder will look for the value in the session for the value in the old input, then it will look in the model instance, if it is installed. Otherwise, it will just use empty.
Before it receives the corresponding value, it converts the specified key, for example account_number.id , account_number->id , account_number["id"] . Focus on transformKey

 protected function transformKey($key) { return str_replace(['.', '[]', '[', ']'], ['_', '', '.', ''], $key); } 

Call the keys indicated one at a time:

  • account_number.id => account_number_id
  • account_number->id => account_number->id
  • account_number["id"] => account_number."id"

Then he will split the key by . will return an array of $keys . And check if there is a nested model with $keys[0] , otherwise we return the value of the main model with the converted key. getFormValue ()

Regardless of whether a nested model exists or not, it will receive a value through the data_get () function.

Obviously, the first key and the second one you specified do not work. Third account_number."id" , it will find the nested model successfully, but will not receive the attribute through the way $nestedModel->{"id"} . Use account_number[id] instead, it works well.

 <td>{!! Form::text('account_number[id]')!!}</td> 
+2
source share

To create input controls for model 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 absence of quotation marks around id . The example in the question contains quotes around the id attribute associated with it, which violates this magic. The above code displays the following input element using the id attribute value with respect to Order model account_number :

 <input name="account_number[id]" type="text" value="4"> 

The format specified in the input name attribute allows PHP to parse the POST data as an array. We can get the value represented as a controller, as in this example:

 public function save(Request $request) { $accountNumber = $request->get('account_number'); echo $accountNumber['id']; // '4' ... } 

This feature is important. FormBuilder creates input elements designed to work with automatically grouping PHP request data into arrays. If we pass multiple input elements on the form for a model 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(); } 
+3
source share

How you use LaravelCollective FirmBuilder with model binding is incorrect. Suppose you have data in orders such as:

 { 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 } } 

So now, if you want to display account_number id in a text field, you can write your form constructor as follows:

 {!! 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() !!} 

or

 <td>{!! Form::text('account_number[id]') !!}</td> 

But in the second answer you will get a question when submitting the form. Because in addition to getting the desired value, this line of code also renames the value of the input name attributes to account_number[id] instead of account_number . Therefore, the best option is to use the first solution. Here is a link to model model binding in LaravelCollective: https://laravelcollective.com/docs/master/html#form-model-binding

+1
source share

After trying to implement on my own environment my conclusion is

 {!! 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> 
+1
source share

All Articles