كيفية التعامل مع استجابات JSON للنماذج التي تتضمن تواريخ الكربون على Laravel؟

StackOverflow https://stackoverflow.com//questions/22019714

سؤال

أنا أكتب تطبيقًا بسيطًا جدًا يتطلب مزامنة نماذج Backbone.js ونماذج Laravel 4.تنشأ المشكلة عندما تتضمن نماذج Laravel كربون بلح.تبدو وحدة التحكم Laravel الخاصة بي كما يلي:

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

يستجيب هذا بنجاح بتمثيل JSON لـ $order الذي يستخدمه جانب العميل للبقاء متزامنًا.ومع ذلك، يتم إرجاع تواريخ الكربون كتمثيل لكائن الكربون، مثل هذا:

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

يمكنني أن أتمكن من تفسير هذا على أنه كائن تاريخ جافا سكريبت بسهولة تامة، ومع ذلك، عندما يعود هذا الكائن إلى laravel، يقوم JSON بإزالة Carbon فشل class وEloquent في قراءة ذلك كتاريخ:

[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} [] []

لذلك أحتاج إما إلى:

  1. قم بتوسيع فئة JsonResponse لتحويل تواريخ الكربون إلى تمثيلات سلسلة.
  2. قم بتوسيع فئة Eloquent لتفسير كائنات StdClass الخاصة بـ Carbon هيكل الفصل حتى التواريخ.
  3. افعل شيئًا من الواضح أنني أفتقده، يدعي Laravel 4 أنه رائع في REST لذا أعتقد أنني أفتقد شيئًا ما.
هل كانت مفيدة؟

المحلول

أولا، أقترح عليك فصل API من وحدات التحكم.استخدام الموارد لمكالمات API.

بالنسبة للكائن الذي تم إرجاعه إلى Larvel، لا أعرف كيف تقوم بمعالجة ذلك للحصول على الخطأ، ولكن يجب عليك بدء مثيل كالي جديد إذا كنت تريد تاريخ الكربون.آخر يمكنك فقط إرجاع التاريخ كسلسلة، وسيتعامل نموذج Larvel في الراحة.

على افتراض الكائن الذي تم إرجاعه هو:

giveacodicetagpre.

وسيحتوي بيانات $ على الاستجابة الحالية، يمكنك ببساطة الكتابة فوق تسليمها_AT:

giveacodicetagpre.

أو إذا كنت تريد كائن الكربون:

giveacodicetagpre.

نصائح أخرى

قد يأتي هذا متأخرًا بعض الشيء، لكنني عادةً ما أستخدم أدوات الوصول والمتحولات لتحقيق ذلك.على سبيل المثال، إذا كنت أريد كل شيء created_at و updated_at الحقول التي سيتم إرجاعها دائمًا بتنسيق ATOM، أقوم بإنشاء فئة نموذج أساسية ممتدة Eloquent الذي يرثه كل نموذج آخر:

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

قد لا يكون هذا هو نفسه لكنني سأحصل على هذا الخطأ عند العمل مع الطوابع الزمنية والكربون ولكن باستخدام strtotime () على البيانات التي كنت أبعز قضيتي، قد تساعدك.

سيكون لكيفية التعامل مع التواريخ في كل من العمود الفقري وLaravel تأثير.
تحتاج إلى اختيار تنسيق تاريخ واحد والالتزام به.ثم تأكد من تحويل كلا الجانبين إلى هذا التنسيق عند تمرير البيانات ذهابًا وإيابًا إلى JS ووحدات التحكم.

إذا قمت بإرسال كائن JavasScript Date خالص، فإنه يقوم بإرجاع سلسلة تاريخ تبدو هكذا
"Sat Apr 19 2014 00:00:00 GMT+0200 (South Africa Standard Time)"
وهو ليس لطيفًا جدًا، منذ لغة PHP strtotime ينتهي بتحليله بطريقة غير تقليدية.

هنا مثال:

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

لماذا هذا التاريخ؟ ربما يستطيع شخص آخر أن يشرح بشكل أفضل مني.يمكنك استخدام تنسيق تاريخ مخصص لقراءته بشكل صحيح، ولكن بدلاً من ذلك استخدم تنسيقًا يمكن لكليهما فهمه.

مثل ISO8601

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

وفي php Carbon يجب أن يكون قادرًا على التعامل معها دون مشاكل

إذا كنت ترغب في الحصول على عمود تاريخ النموذج الخاص بك (created_at) بتنسيق سلسلة استخدم مثل هذا:

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

هذا سوف يتغير

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

في هذا:

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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top