-4

in Course model this relation are include

public function course_modules()
    {
        return $this->hasMany(CourseModule::class, 'course_id');
    }

    public function course_lessons()
    {
        return $this->hasMany(CourseLesson::class, 'course_id');
    }

    public function course_contents()
    {
        return $this->hasMany(CourseContent::class, 'course_id');
    }

i want to make a array for hasMany relation like

$hasMany=[
    CourseModule::class,
    CourseLesson::class
]
Akash
  • 1
  • 1
  • I assume you want to automatically get the relations defined in your model, the reason why you used the reflection class to determine the return value of any method defined in said model. But I can't think of a real use case of doing so. First of all, all relations have to be defined, why not define the hasMany classes in a separate method like `public function getHasManyRelations() { ... }`? Just wondering .. something like @Harshan Madhuranga proposed in his answer. – dbf Jan 15 '23 at 12:57

2 Answers2

1

I wanted to do this for fun, turned out pretty difficult, but here you go, there are some requirements you need to make sure of, but it gets the job done, I will be using a mix of PHP & Laravel to accomplish this.

Step 1: Make sure your main class has proper return method types. So in your case.

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;

class Course extends Model
{    
    public function course_modules() : HasMany
    {
        return $this->hasMany(CourseModule::class, 'course_id');
    }

    public function course_lessons() : HasMany
    {
        return $this->hasMany(CourseLesson::class, 'course_id');
    }

    public function course_contents() : HasMany
    {
        return $this->hasMany(CourseContent::class, 'course_id');
    }
}

Step 2: In your controller, you need to use ReflectionClass, would love if someone actually can improve this for learning purposes.

<?php

namespace App\Http\Controllers;

use ReflectionClass;

class CourseController extends Controller
{
    public function test(){
        //We will build a hasMany array
        $hasMany = [];
        
        //here we will use ReflectionClass on our primary class that we want to use.
        $reflection = new ReflectionClass(new \App\Models\Course);
        
        //Lets loop thru the methods available (300+ i don't like this part)
        foreach($reflection->getMethods() as $method){
            
            //if the method return type is HasMany
            if($method->getReturnType() != null && $method->getReturnType()->getName() == 'Illuminate\Database\Eloquent\Relations\HasMany'){
                //we grab the method name
                $methodName = $method->getName();
                //then we finally check for the relatedClass name and add to the array
                array_push($hasMany, get_class(($instance = new Course)->$methodName()->getRelated()));
            }
        }
        
        //lets dump to see the results
        dd($hasMany);
    }

Results: an array of the classes :D

array:2 [▼ 
  0 => "App\Models\ProgramTest",
  1 => "App\Models\ProgramAnotherTest"
]
RG Servers
  • 1,726
  • 2
  • 11
  • 27
  • 1
    but I think what OP meant is that he wants to declare relations via an array and it would be usable as an eloquent relation. – N69S Jan 15 '23 at 09:07
  • 1
    @N69S if that's the case then I did backwards of what he is requesting – RG Servers Jan 15 '23 at 09:09
  • 2
    Yeah but if that's the case, that would need some heavy rework of Eloquent model methods. Nice piece of code anyway gonna safekeep it for the future :) – N69S Jan 15 '23 at 09:14
  • 1
    It would honestly be a very difficult thing to do – RG Servers Jan 15 '23 at 09:16
  • 2
    Without extensive research, I think it is possible by overloading the methods `getAttribute()` and `__call()` of the eloquent model but the hassle is not worth the saved code lines. – N69S Jan 15 '23 at 09:21
0

According to syntax, we are not able do this in Laravel. However, you can use an model mutors to solve this issue.

public function getCourseDetailsAttribute(){
  $arr=[
     "course_modules"=>$this->course_modules(),
     "course_lessions"=>$this->course_lessons(),
  ];
  return $arr;
}

In the Controller you can write like this,

$course=Course::find(1)->course_details;

For more details t; https://laravel.com/docs/5.7/eloquent-mutators