Yii2: Enhancement: ActiveRecord::link()

Created on 19 Oct 2016  路  3Comments  路  Source: yiisoft/yii2

I was working on a project recently and i came across a situation where i think it would be useful if yii\db\ActiveRecord::link() would return the new record.

Let's take a simple scenario: a reservation system

This would make use of 4 entities mainly:

  • User (id, other fields)
  • Package (id, other fields)
  • Reservation (id, userId, packageId, other fields)
  • Invoice (id, reservationId, userId, other fields)

Assume i reach the point when the user is making a reservation:

public function makeReservation()
{
    $user = Yii::$app->user->identity;
    $package = Package::find()->one();

    $user->link('reservations', $package);

    // $invoice = ...
    // at this point i don't know the reservationId to create an invoice.
}

To solve this currently, we would need to manually create the Reservation record and then again create the Invoice record or simply use the link method

But it would be easier if we could do like this:

public function makeReservation()
{
    $user = Yii::$app->user->identity;
    $package = Package::find()->one();

    $reservation = $user->link('reservations', $package);

    $invoice = $reservation->link('invoice', $user);

    Yii::$app->mailer->compose('invoice', [
            'invoice' => $invoice,
        ])
        ->setFrom(Yii::$app->params['noreplyEmail'])
        ->setTo($user->email)
        ->setSubject('Invoice for package...')
        ->send();
}
db

Most helpful comment

with PHP7 and return type hinting, PHP is moving to a functional programming language. More and more we are depending on methods having one singular responsibility.

In this example this would mean that the singular responsibility of php->link() would be to 'link' two models. The logical result would be a boolean if this objective has been met (similar to ->save())

Howver, to accomplish your goal, you would have to look in another approach. This could be something like php ->getSavedLink(), a getter in which php->link() is called. The name of this method is clearer and return type hinting could be enabled (of course taken the comment of @Ni-san into account )

All 3 comments

  1. Junction table may be used without AR (\yii\db\ActiveQuery::viaTable).
  2. What should return link if relation defined without "via"?
  3. If #5341 will be realized someday, method link will (maybe, maybe not) create two records in two junction tables. What should it return then?

with PHP7 and return type hinting, PHP is moving to a functional programming language. More and more we are depending on methods having one singular responsibility.

In this example this would mean that the singular responsibility of php->link() would be to 'link' two models. The logical result would be a boolean if this objective has been met (similar to ->save())

Howver, to accomplish your goal, you would have to look in another approach. This could be something like php ->getSavedLink(), a getter in which php->link() is called. The name of this method is clearer and return type hinting could be enabled (of course taken the comment of @Ni-san into account )

Was this page helpful?
0 / 5 - 0 ratings