Home > Software design >  Laravel API Resource With Many-to-many Relation Causes Error
Laravel API Resource With Many-to-many Relation Causes Error

Time:06-13

I have a many-to-many relationship between users and roles without any problem. I have UserResource and RoleResource classes work well separately. But I receive an error when I try the following code:

// UserController

public function index()
{
    $users = User::with('roles')->get(); // This gives me the users with roles without any issue.
    return UserResource::collection($users);
}




// UserResource
public function toArray($request)
{
    return  [
        'id' => $this->id,
        'name' => $this->name,
        'roles' => RoleResource::collection($this->whenLoaded('roles'))
    ];
}



// RoleResource
public function toArray($request)
{
    return  [
        'id' => $this->id,
        'name' => $this->name,
    ];
}

The error:

Call to a member function first() on null in file /var/www/html/vendor/laravel/framework/src/Illuminate/Http/Resources/CollectsResources.php on line 34

The function on the CollectResource class is being called twice during this request. On the first time, it received the user with roles, and on the second time null. But it shouldn't be null because I know the user has at least one role. So what am I missing here?

UPDATE: My User model

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable, SoftDeletes;

    protected $fillable = [
        'name',
        'email',
        'password',
        'is_active',
        'settings',
    ];

    protected $hidden = [
        'password',
        'remember_token',
    ];

    protected $casts = [
        'email_verified_at' => 'datetime',
        'roles' => 'array',
        'settings' => 'array',
    ];

    protected static function newFactory()
    {
        return UserFactory::new();
    }

    public function roles()
    {
        return $this->belongsToMany(Role::class, 'positions')->using(Position::class);
    }

}

CodePudding user response:

//User model

protected $casts = [
        'email_verified_at' => 'datetime',
        //'roles' => 'array', // remove this
        'settings' => 'array',
    ];

you're using casting to array not as supposed, docs says that this type of casting created for json or json serialized text columns. without this cast resources works just fine

  • Related