User relations - how to use properly

Hi,

I’m a newbie at yii so please be patient ;D I’ve been reading documents and posts for days now and just can’t seem to make any progress so I thought I’d ask the forum.

I’m trying to create an application (based on the basic application) that has a db schema something like this:

Many Users can belong to an Organisation

An Organisation has many Datasets

A Datasets has many Filesets

A Fileset has many Files

The User, Organisation, Datasets, Fileset, Files are all tables with the correct FK relations setup.

I’ve got GII to spit out the Models and CRUD correctly. The models have all nice relations setup thanks to GII. For example:

User has


 /**

     * @return \yii\db\ActiveQuery

     */

    public function get Organisation()

    {

        return $this->hasOne(Organisation::className(), ['id' => 'organisation_id']);

    }

Organisation has




    /**

     * @return \yii\db\ActiveQuery

     */

    public function getDatasets()

    {

        return $this->hasMany(Dataset::className(), ['organisation_id' => 'id']);

    }

Dataset has


/**

     * @return \yii\db\ActiveQuery

     */

    public function getFilesets()

    {

        return $this->hasMany(Fileset::className(), ['dataset_id' => 'id']);

    }

I’ve got the Login Form linked to the User table following http://www.yiiframework.com/doc-2.0/guide-security-authentication.html

But where I’m stuck is in the next part I’m trying to achieve:

  1. When a User is logged I want him to be able to go to organisation/index and edit only his organisation details. As expected at the moment when I go there I see all organisation listed and can edit any.

  2. When a User is logged in I want him to be able to go to datasets/index and edit only the datasets that his organisation has created . As expected at the moment when I got there I see all the datasets that any Organisation has created.

  3. Finally I want a User to be able to go to fileset/index and edit only the filesets that are part of the datasets that his organisation has created. As expected at the moment at the moment I see any filesets that are part of any dataset that any organisation made.

I’ve looked around at heaps of examples and I see people (e.g) creating WHERE statements and performing JOINs back to different tables but I feel like all these are reinventing the wheel…each model already knows how its related to other models via the function that GII created. So isn’t there an easier way to make this happen?

For example:

  1. is there a way for to apply a filter that uses User->getOrganisation()

  2. is there a way to apply a filter that uses the organisations getDatasets() to only show that users->organisations->datasets?

  3. is there a way to apply a file that uses a selected datasets getFileset() to only show that users->-organisations->datasets->filesets?

Any help would be appreciated to point me in the right direction.

Thanks

Maybe something like this?




public function getDatasets()

{

    $query = $this->hasMany(Dataset::className(), ['organisation_id' => 'id']);

    $query->andWhere( /* your condition using User->getOrganisation() */);

    return $query;

}



More info on ActiveQuery:

http://www.yiiframework.com/doc-2.0/yii-db-querytrait.html#andWhere()-detail

Thanks Patrick. You comment shunted me in the right direction. So I’ve been doing some more reading and watching some ofthese videos and I’ve made some progress. Just wanted some general advice on a good practice structuring a few things:

  1. I’ve started using the advanced template and have started using GII to create models in common, then extending them in the frontend models using code like this



use common\models\X as BaseX;


class X extends BaseX{



so that I can keep updating the base models via Gii as the DB changes and not loose any code. Also I can use different code for them by extending them in the backend\models. So basically I will end up with 3 models

common\models\X (generated by Gii)

frontend\models\X (extended from common\models\X)

backend\models\X (extended from common\models\X)

Good or bad practice?

  1. In reference to my original post about limiting what a model can return (only return relations that the Users->organisation owns), I found I can override find() in my frontend extended classes like this:

 public static function find()

    {

        return parent::find()->where(['organisation_id'=>Yii::$app->user->identity->organisation_id]);

    }

That way any function that uses find will only return that users->organisations records. But my question is, is there a better way to do this? I read that the find can be bypassed by using ->where(). But I never what this to be able to be bypassed, I always want it to be limited. Is there a better way to do this?

Thanks,

bw