Laravel Eloquent — сохранение, обновление и удаление запроса в связанных таблицах

Я пытаюсь разработать какой-то API с Laravel 5.4 и пытаюсь сохранить, обновить и удалить продажи с соответствующими данными о продажах, но до сих пор не продвинулся вперед после попытки и просмотра множества примеров кода, найденных здесь. Я хочу иметь возможность:

  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 и хотел бы получить помощь в этом. Заранее спасибо.


person zinobills    schedule 15.06.2017    source источник
comment
Вы установили защищенные свойства $fillable или $guarded в своих моделях? Это предотвратит массовое присвоение, если оно не будет правильно спланировано.   -  person    schedule 15.06.2017
comment
Да, пожалуйста, я также установил это на две модели для массового назначения.   -  person zinobills    schedule 15.06.2017
comment
опубликуйте свои модели с этими свойствами, пожалуйста.   -  person    schedule 15.06.2017
comment
опубликуйте обновление, пожалуйста   -  person zinobills    schedule 15.06.2017
comment
Убедитесь, что вы не включаете скрытые поля _token или _method, когда пытаетесь сохранить модель. В методе сохранения продаж: $sale = Sale::create($request-›except(['sale_details'])); там может быть больше входных данных, чем вы думаете.   -  person    schedule 15.06.2017
comment
На самом деле они не включены; $sale = Sale::create($request-›except(['sale_details'])); - работает нормально и сохраняет данные о продажах, но данные о продажах вообще не сохраняются в соответствующей таблице.   -  person zinobills    schedule 15.06.2017


Ответы (2)


Попробуйте сохранить модели 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
    }
  ]
person Community    schedule 15.06.2017
comment
Используя это - $details = SalesDetail::create($request-›only(['sale_details'])); сохранить детали продаж не работает. Тоже попытка зациклиться и сохранить тоже не получается вроде; $m_details = $request-›sale_details; foreach ($m_details as $detail){ $details = SalesDetail::create($detail); // вернуть $details; } - person zinobills; 15.06.2017
comment
У меня такое ощущение, что ваш SaleDetail не может быть сохранен, потому что вы включаете поля id, created_at и updated_at. но ваша модель допускает только категорию, меню, единицу измерения, количество и стоимость. - person ; 15.06.2017
comment
Нет пожалуйста, я отправляю эти данные через запрос: - { квитанция: RT555, клиент: Джон Дюмело, total_cost: 1000, amount_paid: 900, payment_type: Наличные, Discount_percent: 0.1, Discount_amount: 100, sale_details: [ { категория: Пицца , меню: Мясоед, единица: Большая, количество: 10, стоимость: 50 }, { категория: Пицца, меню: Мясолюб, единица: Большая, количество: 10, стоимость: 50 } ] } - person zinobills; 15.06.2017
comment
Да, пожалуйста, я отфильтровал его, но все еще не сохраняет - person zinobills; 15.06.2017
comment
Попробуйте выполнить простой тест, сохранив только одну модель SaleDetails и не используя create() или fill(), явно задайте каждое свойство, а затем вызовите save() для модели. - person ; 15.06.2017
comment
Я только что сделал это, но это тоже не работает. пожалуйста, найдите выше обновленный код для функции сохранения. надеюсь, что я не делаю что-то не так там. - person zinobills; 15.06.2017
comment
Какую ошибку или исключение вы получаете? У вас есть лог-файлы? - person ; 15.06.2017
comment
Использование Postman для передачи данных и его статус: 500 Internal Server Error. И нет, у меня нет файлов журнала, пожалуйста - person zinobills; 15.06.2017
comment
Теперь я могу работать с функцией «Сохранить», и она работает нормально, теперь у меня остались функции * «Обновление» и «Удалить», с которыми мне нужна помощь. - person zinobills; 16.06.2017

Контроллер продаж – функция сохранения (обновлено – теперь работает нормально)

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';
}
person zinobills    schedule 16.06.2017