i have an Laravel object model with accessor:
class NutritionalPlanRow extends Model
{
    use HasFactory;
    private $nomeAlimento;
    public function __construct($aliment = null,
                                array $attributes = array())  {
        parent::__construct($attributes);
        if($aliment){
            $this->aliment()->associate($aliment);
            $this->nomeAlimento = $aliment->nome;
        }
    }
    public function aliment()
    {
        return $this->belongsTo('AppModelsAliment');
    }
    protected $guarded = [];
    public function getNomeAlimentoAttribute()
    {
        return $this->nomeAlimento;
    }
}
and i want to print the nomeAlimento value in a Blade page with Blade statement, for example:
 .
 .
 <tbody>
     @foreach( $plan->nutritionalPlanRows as $planRow )
     <tr>
         <td>
             {{ $planRow->nomeAlimento}}
         </td>
   .
   .
but the value inside the table cell is not printed, as if $planRow->foodName is null. In reality it is not empty, in fact if I print {{$planRow}} the structure of the object is complete, and all the attributes are set. I noticed that if in the model I remove the accessor (getNomeAlimentoAttribute()), then the value in the blade page is correctly printed.
Why?
Thanks.
Advertisement
Answer
There are a few things that need attention:
First: Why do you need a constructor? You can define a calculated attribute without the constructor
use AppModelsAliment;
class NutritionalPlanRow extends Model
{
    use HasFactory;
  
   
    public function aliment()
    {
        return $this->belongsTo(Aliment::class);
    }
    protected $guarded = [];
    public function getNomeAlimentoAttribute()
    {
        return optional($this->ailment)->nome;
    }
}
Second: It seems like a code smell when using constructor in Eloquent Model class to set relations. Ideally relations should be set/associated from within Controller.
Third: I feel declaring $nomeAlimento as private property on the class is not required. In Laravel calculated properties/attributes can be provided with accessors.
Update:
class Patient extends Model
{
    use HasFactory;
    protected $dates = ['day_born'];
    protected $guarded = [];
    public function getYearsAttribute(){
        
        Log::info('patient all data '.$this);  //Print correct all data
        Log::info('Day'.$this->day_born); //print empty
        
        
        return Carbon::parse($this->day_born)->diffForHumans(now());
    }
}
Read https://carbon.nesbot.com/docs/ for more goodies.