Laravel 5.2 在同一页面更新 Eloquent Master Detail

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36240015/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 13:28:32  来源:igfitidea点击:

Laravel 5.2 update Eloquent Master Detail on same page

phplaravel

提问by mememoremore

Here are the two models,blade page and controllers I have for implementing the master-detail page in Laravel 5.2. I would like to know how I can update detail part back to database.

这是我在 Laravel 5.2 中实现主从页面的两个模型,刀片页面和控制器。我想知道如何将详细信息部分更新回数据库。

1) Master Model

1) 主模型

namespace App;

use Illuminate\Database\Eloquent\Model;

class Order  extends Model
{
    protected $fillable = [
        'id',
        'name',
        'created_at',
        'updated_at'
    ];

    public function detail()
    {
        return $this->hasMany('App\OrderDetail','fid','id');
    }   



    public function getDetailCountAttribute()
    {
        return $this->hasMany('App\OrderDetail','fid','id')->count();
    }       


    public static function boot()
    {
        parent::boot();    

        // cause a delete of a product to cascade to children so they are also deleted
        static::deleted(function($order)
        {
            $order->detail()->delete();
        });
    }    
}

2) Detail Model

2) 细节模型

namespace App;

use Illuminate\Database\Eloquent\Model;

class OrderDetail extends Model
{
    protected $fillable = [
        'id',
        'oid',
        'item',
        'total',
        'created_at',
        'updated_at'
    ];
}

3) The master detail page (partial), in OrderDetail part, jQuery applied to dynamically add items in the table.

3)母版详情页(部分),在OrderDetail部分,应用jQuery动态添加表项。

<body>
    <h1>Order Edit</h1>
        {!! Form::model($order,['method' => 'PATCH','route'=>['order.update',$order->id]]) !!}
    <div class="form-group">
        ORDER ID:{{$order->id}}
        <br /><br />
    </div>
    <div class="form-group">
        {!! Form::label('order Name', 'ORDER NAME:') !!}
        {!! Form::text('name',$order->name,['class'=>'form-control']) !!}
    </div>
    <div class="form-group">
     <!--order detail part start-->   

    <br />
    {{ Form::select('productInput', $product,'',['ID'=>'productInput']) }}

    {{ Form::number('productQtyInput','',['class'=>'form-control','style'=>'width:250px','ID'=>'OrderQtyInput']) }}


    {{ Form::button('Add',['onclick'=>'product_add();']) }}

    <br />
    <table class="table table-striped table-bordered table-hover" style="width:30%;" border=1 id="TblOrderList" >
        <thead>
             <tr class="bg-info" id="ingHEADER">
                 <th width=2%>PRODUCTID</th>
                 <th width=5% >PRODUCT</th>
                 <th width=5%>QTY</th>
                 <th width=5% colspan=2>COMMAND</th>
             </tr>
        </thead>
        <tbody>
        </tbody>
    </table>        
     <!--order detail part end-->   
    </div>
    <div class="form-group">
        {!! Form::submit('Update', ['class' => 'btn btn-primary']) !!}
    </div>
    {!! Form::close() !!}
</body>

<script type="text/javascript">
function product_add(){
    var ingID =$( "#productInput").val();
    var ingName =$( "#productInput option:selected").text();
    var ingQty =$("#productQtyInput").val();

    var rowCount = $('#TblOrderList .ingData').length;
    rowCount++;


    var outHTML =
        '<tr class="ingData" id="ingRow' + rowCount + '">'
            + '<td><div id="ingID' + rowCount + '">' + ingID + '</div></td>'
            + '<td><div id="ingName' + rowCount + '">' + ingName + '</div></td>'
            + '<td><input type="number" id="ingQTY' + rowCount + '" value="' + ingQty + '"/></td>'
            + '<td>'
                + '<button class="OrderREMOVE" type="button">DELETE</button>'
                + '<button class="OrderUP" type="button">up</button>'
                + '<button class="OrderDOWN" type="button">down</button>'
            + '</td>'
        + '</tr>';

    $('#TblOrderList tr:last').after(outHTML);
    $('#ingUNIT' + rowCount)
        .find('option[value="' + ingUnit + '"]')
        .prop('selected', 'selected');

}
</script>

4) Finally the update function in OrderController, currently it can update the master part. But I am not sure how to loop each detail and update them in same function.

4)最后是OrderController中的update函数,目前可以更新master部分。但我不确定如何循环每个细节并在同一个函数中更新它们。

public function update(Request $request, $id)
{
    //
   $orderUpdate = $request->all();
   $order = Order::find($id);
   $order->update($orderUpdate);


   return redirect('order');        
}

回答by Luís Cruz

You have two options to make that work:

您有两种选择来完成这项工作:

  1. Either you make a request for each OrderDetail item (in this case you have to POST the values via ajax and you can keep your controller code)
  2. Or you make an array of inputs, submit all data at once, and process those inputs on the server.
  1. 要么为每个 OrderDetail 项目发出请求(在这种情况下,您必须通过 ajax 发布值,并且可以保留控制器代码)
  2. 或者您制作一组输入,一次提交所有数据,然后在服务器上处理这些输入。

If you opt for the second option, you'll need to add []to your input name in order to make that input an array. Actually, you don't even have a name on your input, so your controller will never receive the values of that input, as they are not present on the POST variables.

如果您选择第二个选项,您将需要添加[]到您的输入名称以使该输入成为一个数组。实际上,您的输入甚至没有名称,因此您的控制器永远不会收到该输入的值,因为它们不存在于 POST 变量中。

So you need something like:

所以你需要这样的东西:

<input type="number" name="qty[]" id="ingQTY' + rowCount + '" value="' + ingQty + '"/>

Note to the name="qty[]"

注意事项 name="qty[]"

On the controller side, you just need to:

在控制器方面,您只需要:

public function update(Request $request, $id)
{
    // Update the order
    $orderUpdate = $request->all();
    $order = Order::find($id);
    $order->update($orderUpdate);

    // Go through all qty (that are related to the details, and create them)
    foreach ($postValues['qty'] as $qty) {

        $order->detail()->create([ 
            'oid' => $order->id,
            'total' => $qty,
        ]);
    }
    return redirect('order');       
}

This should give an idea of what you need. Of course you should probably submit the order detail id and check on the controller if that id exists and only update the detail when that value exists. If it doens't exist, that you create the detail.

这应该可以让您了解您需要什么。当然,您应该提交订单详细信息 id 并检查控制器是否存在该 id,并且仅在该值存在时更新详细信息。如果它不存在,则您创建详细信息。

I also thing you're missing a few inputs for the order detail (on the javascript part), since the model has a itemattribute and you don't seem to create an input for that column.

我还认为您缺少订单详细信息的一些输入(在 javascript 部分),因为模型有一个item属性,而您似乎没有为该列创建输入。