【问题标题】:Laravel Eloquent - Saving, Updating and Deleting request into related tablesLaravel Eloquent - 将请求保存、更新和删除到相关表中
【发布时间】:2017-06-15 13:46:27
【问题描述】:

我正在尝试使用 Laravel 5.4 开发某种 API,并一直在尝试保存、更新和删除销售及其相关的销售详细信息,但在尝试并浏览了许多找到的代码示例后仍然没有取得任何进展这里。 我希望能够:

  1. 保存销售额及其销售详情(无需一一映射字段)
  2. 更新销售及其销售详情(无需逐一映射字段)
  3. 一次性删除销售及其详细信息。

下面是我的代码

销售模式关系

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use App\Models\SalesDetail;

class Sale extends Model
{
//
  protected $fillable=[
    'receipt',
    'customer',
    'total_cost',
    'amount_paid',
    'payment_type',
    'discount_percent',
    'discount_amount'

  ];

  // a sale has many sales details
  public function saleDetails(){
    return $this->hasMany('App\Models\SalesDetail');
  }
}

销售细节模型关系

 namespace App\Models;

 use Illuminate\Database\Eloquent\Model;
 use App\Models\Sale;

 class SalesDetail extends Model
 {
  //
  protected $fillable=[
    // 'sales_id',
    'category',
    'menu',
    'unit',
    'quantity',
    'cost'

   ];

   // A sales detail  belongs to a sale
   public function sale(){
    return $this->belongsTo('App\Models\Sale');
   }
 }

销售控制器 - 保存功能(更新 - 现在可以正常工作)

public function store(Request $request)
  {
    //Validate request data
     $this->validate($request,['receipt'=>'required']);

     //Save sales without sales details data
    $sale = Sale::create($request->except(['sale_details']));

    //Get sales details data
    $saledetails = $request->sale_details;

    //Loop through sales details
    foreach ($saledetails as $data){

        //Create a new instance of sales details model
        $details = new SalesDetail;

        //fill the model properties (mass assignment) with the data
        $details->fill($data);

        //Save and link sales details to sales 
        $sale->saleDetails()->save($details);

    }

    return 'Sale saved successfully';
}           

销售主管 - 更新功能

 public function update(Request $request, $id)
{
    //
      $this->validate($request,['receipt'=>'required']);

    $sale = Sale::with('saleDetails')->findOrFail($id);

    $input=$request->all();
    $sale->fill($input)->save();

    return 'Sale updated successfully';
}

销售主管 - 删除功能

public function destroy($id)
{
    //
    Sale::with('saleDetails')->whereId($id)->first()->delete();

    return 'Sale deleted sucessfully';
}

销售数据示例

{
"id": 1,
"receipt": "RT124558",
"customer": "John Dumelo",
"total_cost": 1000,
"amount_paid": 900,
"payment_type": "Cash",
"discount_percent": 0.1,
"discount_amount": 100,
"created_at": "2017-06-12 00:00:00",
"updated_at": "2017-06-12 00:00:00",
"sale_details": [
    {
        "id": 1,
        "sale_id": 1,
        "category": "Pizza",
        "menu": "Meat Eater",
        "unit": "Large",
        "quantity": 10,
        "cost": 50,
        "created_at": "2017-06-14 00:00:00",
        "updated_at": "2017-06-14 00:00:00"
    },
    {
        "id": 2,
        "sale_id": 1,
        "category": "Pizza",
        "menu": "Meat Deluze",
        "unit": "Medium",
        "quantity": 5,
        "cost": 30,
        "created_at": "2017-06-14 00:00:00",
        "updated_at": "2017-06-14 00:00:00"
    }
  ]
}

我是 Laravel 的新手,希望能在这方面得到帮助。 先感谢您。

【问题讨论】:

  • 您是否在模型上设置了受保护的 $fillable 或 $guarded 属性?如果没有正确映射,这将阻止批量分配。
  • 是的,我在这两个模型上也设置了批量分配
  • 请发布具有这些属性的模型。
  • 请发布更新
  • 在尝试保存模型时检查以确保不包含 _token 或 _method 隐藏字段。在销售保存方法中: $sale = Sale::create($request->except(['sale_details']));那里的输入数据可能比您意识到的要多。

标签: php mysql eloquent laravel-5.4


【解决方案1】:

尝试独立保存 Sale 和 SaleDetail 模型,然后通过以下方式关联它们:

$sale->saleDetails()->associate($details); 

根据您的 SaleDetails 模型,您需要对其进行过滤:

"sale_details": [
    {
        "id": 1,
        "sale_id": 1,
        "category": "Pizza",
        "menu": "Meat Eater",
        "unit": "Large",
        "quantity": 10,
        "cost": 50,
        "created_at": "2017-06-14 00:00:00",
        "updated_at": "2017-06-14 00:00:00"
    },
    {
        "id": 2,
        "sale_id": 1,
        "category": "Pizza",
        "menu": "Meat Deluze",
        "unit": "Medium",
        "quantity": 5,
        "cost": 30,
        "created_at": "2017-06-14 00:00:00",
        "updated_at": "2017-06-14 00:00:00"
    }
  ]

只包括这个:

"sale_details": [
    {
        "category": "Pizza",
        "menu": "Meat Eater",
        "unit": "Large",
        "quantity": 10,
        "cost": 50
    },
    {
        "category": "Pizza",
        "menu": "Meat Deluze",
        "unit": "Medium",
        "quantity": 5,
        "cost": 30
    }
  ]

【讨论】:

  • 使用这个 - $details = SalesDetail::create($request->only(['sale_details']));保存销售详细信息不起作用。也尝试循环和保存也不起作用; $m_details = $request->sale_details; foreach ($m_details as $detail){ $details = SalesDetail::create($detail); // 返回 $details; }
  • 我感觉您的 SaleDetail 无法保存,因为您包含了 id、created_at 和 updated_at 字段。但您的模型只允许类别、菜单、单位、数量和成本。
  • 不,我通过请求发送此数据:- { "receipt": "RT555", "customer": "John Dumelo", "total_cost": 1000, "amount_paid": 900 , "payment_type": "Cash", "discount_percent": 0.1, "discount_amount": 100, "sale_details": [ { "category": "Pizza", "menu": "Meat Eater", "unit": "Large ", "quantity": 10, "cost": 50 }, { "category": "Pizza", "menu": "Meat Lover", "unit": "Large", "quantity": 10, "cost" : 50 } ] }
  • 是的,我已经过滤掉了,但仍然没有保存
  • 尝试一个简单的测试,只保存一个 SaleDetails 模型,不要使用 create() 或 fill(),明确设置每个属性,然后在模型上调用 save()。
【解决方案2】:

销售控制器 - 保存功能(更新 - 现在可以正常工作)

public function store(Request $request)
  {
    //Validate request data
     $this->validate($request,['receipt'=>'required']);

     //Save sales without sales details data
    $sale = Sale::create($request->except(['sale_details']));

    //Get sales details data
    $saledetails = $request->sale_details;

    //Loop through sales details
    foreach ($saledetails as $data){

        //Create a new instance of sales details model
        $details = new SalesDetail;

        //fill the model properties (mass assignment) with the data
        $details->fill($data);

        //Save and link sales details to sales 
        $sale->saleDetails()->save($details);

    }

    return 'Sale saved successfully';
}           

销售控制器 - 更新功能(已更新 - 现在可以正常工作)

 public function update(Request $request, $id)
{
    //
      $this->validate($request,['receipt'=>'required']);

    $sale=Sale::findOrFail($id);
   $saleinput = $request->except(['sale_details']);

    $sale->fill($saleinput)->save();

    $saledetails = $request->sale_details;

    //Delete previous sales details
    SalesDetail::where('sale_id', $id)->delete();

    foreach ($saledetails as $data){
        $details = new SalesDetail;
        $details->fill($data);
        $sale->saleDetails()->save($details);

    }

    return 'Sale updated successfully';
}

销售控制器 - 删除功能(更新 - 现在可以正常工作)

public function destroy($id)
{
    //Delete sales details before deleting sales
    SalesDetail::where('sale_id', $id)->delete();
    Sale::whereId($id)->first()->delete();


    return 'Sale deleted sucessfully';
}

【讨论】:

    猜你喜欢
    • 2015-04-12
    • 2015-05-14
    • 1970-01-01
    • 1970-01-01
    • 2012-12-19
    • 2020-01-18
    • 2013-11-22
    • 2016-06-22
    • 1970-01-01
    相关资源
    最近更新 更多