Trying to wrap my head around how to get this multi relationship thing working
Created 6 years ago by edster

I have a stream (buildings) with an anomaly.field_type.multiple assigned to it (users stream)

I'm trying to get all buildings that have the logged in user assigned to it.

I'm thinking I'm going about this wrong or making it harder then it really should be, any help would be greatly appreciated.

In my controller I have $buildings = $buildingRepository->findByOwner(Auth::user()); and my repository is

public function findByOwner($user)
    {
        $relation = $this->model->getFieldType('owners')->getRelation();
        return $this->model->belongsToMany($relation->getModel(),$relation->getTable(),'entry_id','related_id')->wherePivot('related_id',$user->id)->get();
    }

But this is returning

UserCollection {#2854 ▼
  #items: []
}

Which is confusing the hell out of me... What am I fucking up =/

edster  —  6 years ago Best Answer

So I didn't need to set a belongsToMany on the building model for owners for some reason, I'm assuming it is because this was in my streams model.

public function owners()
    {
        return $this->getFieldType('owners')->getRelation();
    }

What ended up working on me based on @craigberry suggestion was to assign the buildings relation to the users

<?php namespace Emange\CommercialDocsModule\CommercialDocs\Building\Command;

use Anomaly\UsersModule\User\UserModel;
use Emange\CommercialDocsModule\CommercialDocs\Building\BuildingModel;

class AttachBuildingRelationToUser {

    public function handle()
    {
        $user = new UserModel();

        /* @var Hookable $user */
        if (!method_exists($user, 'bind')) {
            return;
        }

        /**
         * Get the user's buildings.
         *
         * @return \Illuminate\Database\Eloquent\Relations\HasMany
         */
        $user->bind(
            'buildings',
            function () {
                /* @var UserModel $this */
                return $this->belongsToMany(
                    BuildingModel::class,
                    'commercial_docs_buildings_owners',
                    'related_id',
                    'entry_id');
            }
        );
    }
}
ryanthompson  —  6 years ago

Hmm.. here is an example of how it's done in Products module (ignore relatives array in link): https://github.com/anomalylabs/store-module/blob/master/addons/anomaly/products-module/src/Category/CategoryModel.php#L149

Also the name should be like buildings() I would think as far as relations naming standards go. No need to use all that stuff in there since you KNOW the model and you KNOW the table. Just write it as Laravel.

return $this->belongsToMany(
            ProductModel::class,
            'products_products_categories',
            'related_id',
            'entry_id'
        );
edster  —  6 years ago

@ryanthompson if i want to be able to search for all entries I'm correct in doing it in the repository and using $this->modelthough right?

I'll give that go first thing in the morning!

ryanthompson  —  6 years ago

Ya if you are doing a search then you wouldn't want a relation though either (and again hardcode the things you need within instead of getting the table name from the stream). Relation would go on the model - search would go on the repository.

Pry use the terminology findAllByOwner as well - which indicates this will be on the BuildingRepository

edster  —  6 years ago Best Answer

So I didn't need to set a belongsToMany on the building model for owners for some reason, I'm assuming it is because this was in my streams model.

public function owners()
    {
        return $this->getFieldType('owners')->getRelation();
    }

What ended up working on me based on @craigberry suggestion was to assign the buildings relation to the users

<?php namespace Emange\CommercialDocsModule\CommercialDocs\Building\Command;

use Anomaly\UsersModule\User\UserModel;
use Emange\CommercialDocsModule\CommercialDocs\Building\BuildingModel;

class AttachBuildingRelationToUser {

    public function handle()
    {
        $user = new UserModel();

        /* @var Hookable $user */
        if (!method_exists($user, 'bind')) {
            return;
        }

        /**
         * Get the user's buildings.
         *
         * @return \Illuminate\Database\Eloquent\Relations\HasMany
         */
        $user->bind(
            'buildings',
            function () {
                /* @var UserModel $this */
                return $this->belongsToMany(
                    BuildingModel::class,
                    'commercial_docs_buildings_owners',
                    'related_id',
                    'entry_id');
            }
        );
    }
}