We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

How to operate with related Model?

If no ORM, it need use this to get all related record

        $user=User::findFirstById(3);
        echo $user->username. ' - ';

        foreach($user->payment as $p)
        {
            echo $p->amount;
        }

        $payment=Payment::find('userId='.$user->id);
        foreach($payment as $p)
        {
            echo $p->amount;
        }

If I use ORM, I can add this to User


    public function initialize()
    {
        $this->hasMany("id", "Payment", "userId");
    }

and I just select once, then I can get all related records

        $user=User::findFirstById(3);
        echo $user->username. ' - ';

        foreach($user->payment as $p)
        {
            echo $p->amount;
        }

Now I have some question

(1.) How to use ORM way to create record? like this

        $user=new User();
        $user->username='username';
        $user->password='password';
        $user->payment->amount=1000;
        $user->save();

not this

        $user=new User();
        $user->username='username';
        $user->password='password';
        $user->save();

        $payment=new Payment();
        $payment->userId=$user->id;
        $payment->payment=1000;
        $payment->save();

(2.) I can use index to get the detail record

    echo $user->payment[0]->amount;

But this is not work in volt, how to get details without loop in volt?

(3.) How to do some operation with related data when I select main model?

For example:

a. find all user, order by max(payment.amount)

b. find all payment, order by user.id


51.2k
Accepted
answer
  1. For finding records, check https://docs.phalcon.io/en/latest/reference/models.html#finding-records
    // Find all payment, order by user id
    $result = Payment::find(
        array(
            "order" => "user_id DESC" // or ASC
        )
    );

For more complex queries, my opinion is that you should use RawSql https://docs.phalcon.io/en/latest/reference/phql.html#using-raw-sql

As for the question related to saving related models, this is how the ORM works. Payments are many objects. You must use it like this:

        $user=new User();
        $user->username='username';
        $user->password='password';
        $user->save();

        $payment=new Payment();
        $payment->userId=$user->id;
        $payment->payment=1000;
        $payment->save();

You can use this only on update and if the relation is one to one:

        $user= User::findFirstById(1);
        $user->username='username';
        $user->password='password';
        $user->payment->amount=1000;
        $user->update();

Other example:

    $user = User::findFirstById(1);

    // This will order the payments of a user by amount desc
    $payments = $user->getPayments(
        array(
            "order" => "amount DESC"
        )
    );

Using a raw sql:

   $sql = "select * from user u join payments p on (p.user_id = u.id) order by p.amount DESC";

   $user = new User();
   $result =  new Phalcon\Mvc\Model\Resultset\Simple(null, $user, $user->getReadConnection()->query($sql));

You can also try with Phql (i'm not a fan of that)

There are so many posibilities. Choose one that fits you.