Search code examples
phpmodelsphalconrelation

PhalconPHP - get specific object with multiple relations


I have a model, call it Robot, which has multiple manyToMany relationships with other models - Part, Country and Permision. Relation models being RobotsParts, RobotsCountries and RobotsPermissions.

Each robot can have multiple or no parts, countries and permissions linked to them.

To get all the robots with a certain part, PhalconPHP makes it easy. (aliases being properly set in models, of course).

$part = Part::findFirstByName("arm");
$robotsWithPart = $part->robots;

The same thing applies for robots with a certain country:

$country = Country::findFirstByCode("HR");
$robotsWithCountry = $country->robots;

But how can one get only robots with a certain part, country and permission?

I've had futile attempts like:

$country = Country::findFirstByCode("HR");
$part = Part::findFirstByName("arm");

$robots = $country->getRobots([
    'conditions' => "(partId = :pid:)",
    'bind' => [
        'pid' => $part->id
    ]
]);

But, of course, partId is not recognized as it doesn't belong to any of the selected models;


Solution

  • You can use the $model->getRelated('model', $parameters = []) option.
    $parameters = [] works the same as how you would normally query a model. i.e; it takes the parameters order, limit, conditions, ...

    $country = Country::findFirstByCode("HR");
    $part = Part::findFirstByName("arm");
    
    $robots = $country->getRelated('Robot', ['partId = ' . $part->id]);
    

    You can find this in the documentation


    UPDATE

    That sounds like it wouldn't be possible. You will have to call a custom query on your Robot model. Something like this:

    $result = Robot::query()
            ->join('Country', 'Country.id = Robot.countryId')
            ->join('Part', 'Part.robotId = Robot.id')
            ->where('Country.code = :code:')
            ->where('Part.name = :name:')
            ->bind(['code' => 'HR', 'name' => 'arm'])
            ->execute();
    

    You can also use the Querybuilder, if you prefer to use that.