Pergunta

Eu estou escrevendo uma bem simples aplicativo que requiers Backbone.js modelos e Laravel 4 modelos para estar em sincronia.Problema surge quando eu o Laravel modelos envolvem De carbono datas.Meu Laravel controlador parecido com este:

class OrderController extends \BaseController {
    ...
    public function update($id = null) {
        ...
        if (Request::ajax()) 
            return $order;
        ...
    }
}

Isto com êxito, responde com uma representação JSON de $ordem de que o cliente usa para ficar em sincronia.No entanto, o Carbono datas são retornados como o Carbono objeto de representação, como este:

{
    "delivered_at":{"date":"2014-02-25 12:55:29","timezone_type":3,"timezone":"America\/Argentina\/Buenos_Aires"}
}

Não consegui interpretar isso como um javascript objeto de Data muito facilmente, no entanto, quando esse objeto vai voltar para laravel, JSON remove o Carbon classe e Eloqüente falha ao ler que como uma data:

[2014-02-25 12:58:32] log.ERROR: exception 'ErrorException' with message 'preg_match() expects parameter 2 to be string, array given' in vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2210
Stack trace:
#0 [internal function]: Illuminate\Exception\Handler->handleError(2, 'preg_match() ex...', '/Users/maurospi...', 2210, Array)
#1 vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(2210): preg_match('/^(\d{4})-(\d{2...', Array)
#2 vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(2151): Illuminate\Database\Eloquent\Model->fromDateTime(Array)
#3 vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(306): Illuminate\Database\Eloquent\Model->setAttribute('delivered_at', Array)
#4 app/controllers/OrderController.php(120): Illuminate\Database\Eloquent\Model->fill(Array)
#5 [internal function]: OrderController->update('91')
#6 vendor/laravel/framework/src/Illuminate/Routing/Controllers/Controller.php(138): call_user_func_array(Array, Array)
#7 vendor/laravel/framework/src/Illuminate/Routing/Controllers/Controller.php(115): Illuminate\Routing\Controllers\Controller->callMethod('update', Array)
#8 vendor/laravel/framework/src/Illuminate/Routing/Router.php(985): Illuminate\Routing\Controllers\Controller->callAction(Object(Illuminate\Foundation\Application), Object(Illuminate\Routing\Router), 'update', Array)
#9 [internal function]: Illuminate\Routing\{closure}('91')
#10 vendor/laravel/framework/src/Illuminate/Routing/Route.php(80): call_user_func_array(Object(Closure), Array)
#11 vendor/laravel/framework/src/Illuminate/Routing/Route.php(47): Illuminate\Routing\Route->callCallable()
#12 vendor/laravel/framework/src/Illuminate/Routing/Router.php(1016): Illuminate\Routing\Route->run(Object(Illuminate\Http\Request))
#13 vendor/laravel/framework/src/Illuminate/Foundation/Application.php(574): Illuminate\Routing\Router->dispatch(Object(Illuminate\Http\Request))
#14 vendor/laravel/framework/src/Illuminate/Foundation/Application.php(550): Illuminate\Foundation\Application->dispatch(Object(Illuminate\Http\Request))
#15 public/index.php(49): Illuminate\Foundation\Application->run()
#16 {main} [] []

Então eu preciso:

  1. Estender a JsonResponse classe para converter Carbono datas para a cadeia de representações.
  2. Estender o Eloqüente classe para interpretar StdClass objetos do Carbon estrutura de classe para as datas.
  3. Fazer algo que eu estou claramente em falta, Laravel 4 afirma ser incrível em REPOUSO, então eu acho que eu estou faltando alguma coisa.
Foi útil?

Solução

Primeiro, sugiro que você separe a API de controladores.Utilizar recursos para chamadas de API.

Para o objeto retornado para Laravel, eu não sei como você está se processando-lo a obter o erro, mas você deve iniciar uma nova Carbono exemplo, se você quer uma data de Carbono.Outra coisa que você poderia retornar a data como uma seqüência de caracteres, Laravel Modelo irá lidar com o resto.

Supondo que o objeto retornado é:

{
    "delivered_at":{"date":"2014-02-25 12:55:29","timezone_type":3,"timezone":"America\/Argentina\/Buenos_Aires"}
}

E a variável $data terá a resposta atual, você pode simplesmente substituir delivered_at:

$data->delivered_at = $data->delivered_at->date;

Ou se você quiser um Carbono objeto:

$data->delivered_at = new \Carbon\Carbon($data->delivered_at->date, $data->delivered_at->timezone);

Outras dicas

Isto pode ser um pouco tarde, mas eu costumo fazer uso de acessores e mutadores para conseguir isso.Por exemplo, se eu quero todos created_at e updated_at campos sempre a ser retornado no formato ATOM, eu criar um modelo de base de classe que estende Eloquent todos os outros modelo herda:

use Carbon\Carbon as Carbon;
use Illuminate\Database\Eloquent\Model as Model;

class BaseModel extends Model {

    public function getCreatedAtAttribute($value)
    {
        return Carbon::parse($value)->toATOMString();
    }

    public function setCreatedAtAttribute($value)
    {
        $this->attributes['created_at'] = Carbon::parse($value)->toDateTimeString();
    }

    public function getUpdatedAtAttribute($value)
    {
        return Carbon::parse($value)->toATOMString();
    }

    public function setUpdatedAtAttribute($value)
    {
        $this->attributes['created_at'] = Carbon::parse($value)->toDateTimeString();
    }
}

Isso pode não ser o mesmo, mas eu conseguiríso este erro ao trabalhar com timestamps e carbono, mas usando strtotime () nos dados que passava resolvido resolvido meu problema, pode ajudá-lo.

Como você lida com as datas em ambos os espinha dorsal e Laravel vai ter um impacto.
Você precisa escolher um formato de data e cumpri-lo.E certifique-se de que ambos os lados se converter para o formato que quando os dados são transmitidos para trás e para a frente para o JS e os Controladores.

Se você enviar um puro JavasScript objeto Date, em seguida, devolve uma cadeia de caracteres de data que se parece com isso
"Sat Apr 19 2014 00:00:00 GMT+0200 (South Africa Standard Time)"
O que não é tão agradável, já que o PHP é strtotime acaba de análise é um funky.

aqui está um exemplo:

$jsdate = "Sat Apr 19 2014 00:00:00 GMT+0200 (South Africa Standard Time)";
$carbon = Carbon::createFromTimestamp(strtotime($jsdate));
$iso8601 = $carbon ->format(Carbon::ISO8601)
//output '1970-01-01T02:00:00+0200' which is a UNIX timestamp 0.

Por que essa data? talvez outra pessoa pode elaborar melhor que eu posso.Você pode usar um formato de data personalizado para lê-lo corretamente, mas, ao invés de usar um formato de tanto pode entender.

Como ISO8601

//javascript
var jsdate = (new Date()).toISOString();

E em php de Carbono deve ser capaz de lidar com ele sem problemas

Se você deseja obter coluna de data de seu modelo (created_at) em formato de seqüência de caracteres use assim:

$response['created_at'] = Carbon::parse($model->created_at)->toDateString();

isso vai mudar

created_at = {"date":"2014-02-25 12:55:29","timezone_type":3,"timezone":"America\/Argentina\/Buenos_Aires"}

para isso:

created_at = "2014-02-25 12:55:29"

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top