4

Im kinda new to rest api, especially with YII2.

I have three tables: students(id, name), courses(id, subject) and students_courses(student_id, course_id). Many to many relation.

I need to get students id, name and courses via relation table.

myexample.com/api/v1/students

gives me json with id and name only

myexample.com/api/v1/students/get-students-courses

gives me 404 not found

Here's my model:

<?php

namespace app\models;

use Yii;

class Students extends \yii\db\ActiveRecord
{

    public static function tableName()
    {
        return 'students';
    }


    public function rules()
    {
        return [
            [['name'], 'required'],
            [['name'], 'string', 'max' => 255]
        ];
    }

    public function attributeLabels()
    {
        return [
            'id' => 'ID',
            'name' => 'Name',
        ];
    }

    public function getStudentsCourses()
    {
        return $this->hasMany(StudentsCourses::className(), ['student_id' => 'id']);
    }
}

and urlManager configuration:

'urlManager' => [
        'enablePrettyUrl' => true,
        'enableStrictParsing' => true,
        'showScriptName' => false,
        'rules' => [
            ['class' => 'yii\rest\UrlRule', 'controller' => ['v1/students']],
        ],
    ],

EDIT: Thanks, Salem Ouerdani, this worked.

public function getCourses()
{
    return $this->hasMany(Courses::className(), ['id' => 'course_id'])
    ->viaTable(StudentsCourses::tableName(), ['student_id' => 'id'])
    ->all();
}

public function extraFields()
{
    return ['studentsCourses' => function(){
        return $this->getCourses();
    }];
}
2
  • Not at all, I'm glad it helped, but one thing to note: with public function getCourses(){...} you can simply have extraFields() {return ['courses'];} and your link will then look like : myexample.com/api/v1/students&expand=courses unless you need it to be named that way. Commented Feb 1, 2016 at 8:37
  • Yii2 (as Yii1) uses getters & setters. so a method like getAbc(){..} can be called like $model->getAbc() or simply like $model->abc. extraFields in this case should return an array with method's getter abbreviation (['abc'] in this case or simply the way how you did it). I'm adding this note as it can help others. Commented Feb 1, 2016 at 8:57

2 Answers 2

2

You need to override your model's extraField() method :

class Students extends \yii\db\ActiveRecord
{

    public function getStudentsCourses() {...}

    ...

    public function extraFields()
    {
        return ['studentsCourses'];
    }
}

Then you should be able to retrieve all students collection with their related courses within :

myexample.com/api/v1/students&expand=studentsCourses

or maybe a single resource like myexample.com/api/v1/students/99&expand=studentsCourses

see docs for more details.

Sign up to request clarification or add additional context in comments.

Comments

1

well, from what i gather you need to add a public function actionGetStudentsCourses() to your StudentsController

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.