Domanda

Sto scrivendo un'app piuttosto semplice che requiliers backbone.js modelli e la laravel 4 modelli da sincronizzare. Problemi sorge quando i modelli di laravel coinvolgono carbonio date. Il mio controller Laravel è simile a questo:

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

Risponde con successo con una rappresentazione JSON di $ ordine che il lato client utilizza per rimanere in sincronia. Tuttavia, le date di carbonio vengono restituite come rappresentazione dell'oggetto del carbonio, come questa:

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

Potrei riuscire a interpretare questo come un oggetto Data JavaScript abbastanza facilmente, tuttavia, quando questo oggetto risale a Laravel, JSON rimuove la classe Carbon ed Eloquente non riesce a leggerlo come una 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} [] []
.

Quindi ho bisogno di:

    .
  1. Estendi la classe JSONSPONSE per convertire le date di carbonio per le rappresentazioni di stringa.
  2. Estendi la classe eloquente per interpretare gli oggetti stdclass della struttura della classe Carbon alle date.
  3. Fai qualcosa che mi manca chiaramente, la Laravel 4 afferma di essere fantastico a riposo, quindi immagino che mi manchi qualcosa.
È stato utile?

Soluzione

In primo luogo, ti suggerisco di separare l'API dai controller.Utilizzare le risorse per le chiamate API.

Per l'oggetto restituito a Laravel, non so come lo stai elaborando per ottenere l'errore, ma dovresti avviare una nuova istanza di carbonio se si desidera una data in carbonio.Altrimenti potresti semplicemente restituire la data come una stringa, il modello di Laravel gestirà il resto.

Supponendo che l'oggetto restituito sia:

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

E i dati Variable $ avranno la risposta attuale, è possibile semplicemente sovrascrivere fornito_at:

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

o se si desidera un oggetto in carbonio:

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

Altri suggerimenti

Questo potrebbe arrivare in un po 'tardi, ma di solito uso gli accessori e i mutatori per raggiungere questo obiettivo.Ad esempio, se voglio che tutti i campi created_at e updated_attagCode siano sempre restituiti nel formato Atom, creo una classe di base Modello che si estende Eloquent che ogni altro modello eredita:

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();
    }
}
.

Questo potrebbe non essere lo stesso ma avrei ricevuto questo errore quando si lavora con timestamps e carbonio, ma usando Strtotime () sui dati che stavo passando risolto il mio problema, potrebbe aiutarti.

Come gestite le date in entrambe la spina dorsale e la Laravel avranno un impatto.
È necessario scegliere un formato di data e attenersi ad esso.Quindi assicurarsi che entrambe le parti convertono in quel formato quando si passano i dati e in avanti rispetto ai JS e ai controller.

Se si invia un oggetto datario JavaScript puro, quindi restituisce una stringa data che assomiglia a questa "Sat Apr 19 2014 00:00:00 GMT+0200 (South Africa Standard Time)"
. Il che non è così bello, dal momento che il strtotime di PHP finisce per analizzarlo un funky.

Ecco un esempio:

$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.
.

Perché quella data? forse qualcun altro può elaborare meglio allora posso. È possibile utilizzare un formato di data personalizzato per leggerlo correttamente, ma utilizzare un formato entrambi possono capire.

Come ISO8601

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

E in PHP Carbon dovrebbe essere in grado di gestirlo senza problemi

Se si desidera ottenere la colonna della data del modello (created_at) in formato stringa Uso come questo:

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

Ciò cambierà

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

In questo:

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top