Формат даты Laravel 5.3 Carbon не установлен при возврате?

У меня есть модель VitalSignSet:

class VitalSignSet extends Model
{
  protected $dates = [
        'datetimetaken',
  ];

  . . .
}

Теперь в моей функции есть эта функция, которая возвращает встречу в кодировке json с последним набором показателей жизнедеятельности. (Encounter имеет отношение hasMany с VitalSignSet) Однако перед возвратом я хотел бы, чтобы поле datetimetaken было отформатировано для удобства чтения человеком, но только для этого конкретного метода. (поэтому я не использовал аксессоры)

public function get(Request $request, Encounter $encounter) {
   // Setting the latest vital sign set
   $encounter->latest_vitals = $encounter->VitalSignSets()
             ->orderBy('datetimetaken','desc')->get()->first();

   // Formatting the date :
   // Works when just returning the date.
   // Does not return in this format when returning the model with the date.
   $encounter->lastest_vitals->datetimetaken->format('M j, Y');

   return $encounter->toJson();
}

Вышеупомянутый метод доступен из запроса js ajax. Когда я анализирую и регистрирую ответ, формат даты и времени не изменился. (все еще в формате YYYY-mm-dd H:i:s) Но когда я возвращаю только $encounter->latest_vitals->datetimetaken; после форматирования, возвращается строка с форматом, который я установил. Но когда я возвращаю содержащую VitalSignSet модель $encounter->latest_vitals; (ответ json), формат будет в YYYY-mm-dd. Это почему?


person James A    schedule 04.11.2016    source источник


Ответы (1)


Это потому, что вы только обращаетесь к объекту данных, вы фактически не меняете его.

К сожалению, нет способа (который мне удалось найти) изменить формат экземпляра Carbon в модели. Это связано с тем, что Laravel использует тот же формат для анализа даты и времени из базы данных, что и для форматирования ее в строку.

Кроме того, вы не сможете просто назначить отформатированную строку оригиналу, поскольку Eloquent попытается проанализировать эту строку (и потерпит неудачу).

Один из способов (если вы хотите / хотите сохранить ключ как datetime) - это преобразовать вывод в массив, отредактировать значение и затем вернуть его:

$latestVitals = $encounter->VitalSignSets()
    ->orderBy('datetimetaken', 'desc')->first();

$encounter->latest_vitals = collect($latestVitals->toArray())
    ->pipe(function ($item) use ($latestVitals) {
        $item['datetimetaken'] = $latestVitals->datetimetaken->format('M j, Y');

        return $item;
    });

return $encounter;

Если вы не против изменить ключ на что-то другое (например, formatted_datetimetaken), вы можете добавить аксессуар к любой модели, которая используется для вас VitalSignSet:

public function getFormattedDatetimetakenAttribute()
{
    return $this->datetimetaken->format('M j, Y');
}

А затем просто используйте append() т.е.

$encounter->latest_vitals = $encounter->VitalSignSets()
    ->orderBy('datetimetaken','desc')
    ->first()->append('formatted_datetimetaken');

Наконец, вы можете просто изменить дату и время в своем js-файле с помощью чего-то вроде http://momentjs.com/docs. Предполагая, что ваш ответ назначен переменной response:

response.latest_vitals.datetimetaken = moment(response.latest_vitals.datetimetaken, "YYYY-MM-DD HH:mm:ss")
            .format("MMM D, YYYY")

Надеюсь это поможет!

person Rwd    schedule 04.11.2016