If you are returning something from your controller then the Laravel will convert it to the string. If you return the object then your object's
__toString() the magic method will be automatically invoked to make the required conversion.
So when you just try to
return your $promotion from the controller action then the Laravel is going to call the magic method
__toString() on it and it will be converted to the string to display.
__toString() calls your
toJson(), which will return you the result of your
json_encode. So now the
json_encode is returning a
false, it clearly suggests that it is running into the error.
I guess your
dd must be showing that your
img attribute is the
json_encode cannot readily encode your
resource, so this is the main reason behind the failure. So you must add your
img attribute to your
$hidden property to try to remove it from your
json_encode as shown below
class Promotion extends Model
protected $hidden = ['img'];
// rest of your class