16

I have a Model Review that has a unix timestamp as 1 of it's attributes (table columns).

I use 2 accessors inside this model:

public function getReviewDateAttribute($value)
{
    return strftime('%A %e %B %Y', $value);
}

public function getReviewDateIsoAttribute()
{
    return Carbon::createFromTimestamp($this->review_date)->toDateTimeString();
}

getReviewDateAttribute works as expected and shows up in the collection of models when I write a query.

However getReviewDateIsoAttribute does not. What could be the reason for this?

A subquestion: If I use the same attribute in both functions, how can I use the original format as input value?

enter image description here

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
online Thomas
  • 8,864
  • 6
  • 44
  • 85

4 Answers4

45

You should be adding it to the $appends array. It isn't spinning through all available methods looking for getXXXXXAttribute. The other one is used because it is an accessor for an actual attribute, this one is not an actual attribute.

class YourModel ....
{
     protected $appends = ['review_date_iso'];
     ...
}

Laravel 5.5 Docs - Eloquent - Serialization - Appending Values to JSON

lagbox
  • 48,571
  • 8
  • 72
  • 83
5

This is probably because ReviewDateIso is not an actual column and therefore will not show up in the model collections...you can access it directly by calling the method directly

$model->getReviewDateIsoAttribute()

According to the docs accessors a ways of changing the value of a column before it is returned to the method that queried it.

If you want it to show up when you call the collection as Json append it to the output with

protected $appends = ['name_of_attribute'];
kofoworola
  • 557
  • 1
  • 5
  • 14
  • 1
    I understand what you try to say, but Laravel `accessors` are "magic" functions that create attributes on the fly, hence this still should work. Please take a look at the documentation's `getFullNameAttribute` example. – online Thomas Dec 18 '17 at 16:17
  • It could also have something to do with the way your query is structures, here's a link to an issue like that https://laracasts.com/discuss/channels/laravel/custom-accessor-not-working-anymore – kofoworola Dec 18 '17 at 16:30
1

I tried queries in tinker and with dd method. So I got confused since I cant view my new accessor in the attribute list.

I thought I missed something. Then later I noticed appended attributes are shown separately when we dd the query result than the usual attribute JSON.

I lost time thinking my accessor is not working. Its just I`m not checking in the right way or right place. So I``m attaching the following image, if anyone gets stuck on accessors like me, this might help them.

enter image description here

Community
  • 1
  • 1
Vineeth Vijayan
  • 1,215
  • 1
  • 21
  • 33
0

In fact it depends on what you are trying to achieve. If you are going to display anything in Blade for example, you can use whenever you want $object->review_date_iso to get this attribute value.

However if you are returning Json responses (for example API), you need to tell Eloquent model to append extra fields to your model when transforming to JSON format.

You probably have review_date attribute in your model (this is the column in database I suppose) but you don't have review_date_iso in your table in database, so in your model you need to use:

protected $appends = ['review_date_iso'];

but you don't have to include here review_date because it's already in your table in database and your accessor will be automatically fired.

Marcin Nabiałek
  • 109,655
  • 42
  • 258
  • 291