I have a Reminder
model that has a sound_path
column. I created an accessor for that column in the model but it's returning null
and I doubled checked that the database has a value in that column. What am I doing wrong?
Note: Of course I can call $this->sound_path
directly in soundPathUrl
mutator without creating the accessor from the first place but I'm interested to know why if I called the accessor is not returning any value.
Reminder
model
namespace App\Models;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\URL;
use Spatie\Translatable\HasTranslations;
class Reminder extends BaseModel
{
use HasFactory, SoftDeletes, HasTranslations;
public $translatable = [
'title__ml',
];
protected $casts = [
'available_days_for_reminder' => 'json',
'is_multiple_days_allowed' => 'boolean'
];
protected $appends = ['sound_path_url'];
/**
* Get the sound path
*
* @param string $value
* @return \Illuminate\Database\Eloquent\Casts\Attribute
*/
protected function soundPath(): Attribute
{
return Attribute::make(
get: fn ($value) => $value
);
}
/**
* Get sound path download URL
*
* @return \Illuminate\Database\Eloquent\Casts\Attribute
*/
protected function soundPathUrl(): Attribute
{
return new Attribute(
get: fn () => asset('storage/' . $this->soundPath),
);
}
}
Reminder
controller
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Http\Resources\Reminder\ReminderCollection;
use App\Http\Resources\Reminder\ReminderResource;
use App\Models\Reminder;
use Exception;
use Illuminate\Http\Request;
class ReminderController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$reminders = Reminder::paginate(5);
return ReminderCollection::collection($reminders);
}
}
ReminderCollection
API resource
namespace App\Http\Resources\Reminder;
use Illuminate\Http\Resources\Json\JsonResource;
class ReminderCollection extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
*/
public function toArray($request)
{
return [
'id' => $this->id,
'title' => $this->title__ml,
'sound' => $this->sound_path_url
];
}
}
Screenshot of Response
At the arrow there should be the value of sound_path.
CodePudding user response:
Your issue is that you are calling $this->soundPath
instead of $this->sound_path
in soundPathUrl
method...
So, you should have this:
/**
* Get sound path download URL
*
* @return \Illuminate\Database\Eloquent\Casts\Attribute
*/
protected function soundPathUrl(): Attribute
{
return new Attribute(
get: fn () => asset('storage/' . $this->sound_path),
);
}
Check the documentation and you will see you still have to call your properties using snake_case
.
CodePudding user response:
It seems
soundPath
accessor does nothing, it returns the same value which seems empty. Where doessoundPath
value come from? First, make sure,soundPath
itself has any value within that function.Call
soundPath
as a function
protected function soundPathUrl(): Attribute
{
return new Attribute(
get: fn () => asset('storage/' . $this->soundPath()),
);
}
}