harryg
harryg

Reputation: 24077

Laravel saving a hasAndBelongsToMany relationship

In my Laravel 4 app I have the models:

As you might have noticed, a payment can have many payers and a payer can have many payments. These models are joined by the PayerPayment model, which also contains the additional fields (amount_paid, included_in_payment) which says how much each Payer paid and whether they should be included in the overall payment.

When I add a new payment I want the form to include inputs for each payer where I can fill in the 2 PayerPayment fields (amount_paid, included_in_payment).

The way I do it at the moment is to pass a record set of payers to the view where I construct the form:

Controller:

public function add()
{
    $payers = Payer::all();
    return View::make('payments.add')->with('payers', $payers);
}

View:

  {{ Form::open( array('route'=>'payments.store', 'class'=>'form-signup')) }}

  {{ Form::input('date', 'payment_date', null, array('class'=>'form-control')) }}
  {{ Form::text('recipient', null, array('class'=>'form-control')) }}

  @foreach ($payers as $payer)
      <fieldset>
      {{ Form::label($payer->id . '-amount', $payer->name) }} <br>
      {{ Form::input('number', $payer->id . '-amount_paid', null, array('class'=>'form-control', 'step' => 'any', 'value' => 0)) }}
      {{ Form::checkbox($payer->id . '-included_in_payment', null, array('class'=>'form-control', 'label'=>'pays')) }}
      {{ Form::label($payer->id . '-included_in_payment', 'pays') }}
     </fieldset>
  @endforeach

  {{ Form::submit('Add Payment', array('class'=>'btn btn-primary')) }} 

  {{ Form::close() }}

Now when I come to save the payment my controller currently looks like this:

$payment = new Payment;
            $payment->payment_date = Input::get('payment_date');
            $payment->recipient = Input::get('recipient');
            $payment->save();

            //Save the amount each payer paid
            $payers = Payer::all();
            foreach ($payers as $payer){
                $payment_payer = new PayerPayment;
                $payment_payer->payment_id = $payment->id;
                $payment_payer->payer_id = $payer->id;

                $payment_payer->amount_paid = Input::get($payer->id . '-amount-paid') ? Input::get($payer->id . '-amount_paid') : 0;

                $payment_payer->included_in_payment = Input::has($payer->id . '-included_in_payment');
                $payment_payer->save();
            }

This seems like a bad way to do things. I am making a new PayerPayment separate from the saving of the parent Payment by looping through all the Payers. Does laravel have a way to acheive this in one go?

Upvotes: 0

Views: 588

Answers (1)

duellsy
duellsy

Reputation: 8575

What you're after is "inserting related models"

So after you save the payment, you can add it to the users like this:

...
$payment->save();

$payers = Payer::all();
foreach ($payers as $payer){

    $extra_details = array(
        'amount_paid' => Input::get($payer->id . '-amount-paid') ? Input::get($payer->id . '-amount_paid') : 0, 
        'included_in_payment' = Input::has($payer->id . '-included_in_payment')
    );

    $payer->payments()->attach($payment->id, $extra_details);

}

Upvotes: 1

Related Questions