2016-12-23 39 views
0

這是laravel 5.3Laravel改變排序

當我預覽使用這個電子郵件:

$wantsheet_products = WantsheetProduct::orderByRaw(EmailService::WANTSHEET_PRODUCT_ORDER_SQL)->get(); 
    View::make('email.wantsheet.email_wantsheet_to_supplier', ['wantsheet_products' => $wantsheet_products]); 

排序是正確的。也就是說,排序是['a','b','c']我想要的方式。

編輯底部

現在看到的音符實際發送了郵件(我排隊它們)時,排序發生變化,再次未排序,魔?構造函數和構建功能

class WantsheetToSuppliersMail extends Mailable 
{ 

    public $wantsheet_products; 
    public $to_email; 
    /** @var WantsheetContact $wantsheetcontact*/ 
    public $wantsheetcontact; 
    use Queueable, SerializesModels; 

    /** 
    * Create a new message instance. 
    * 
    * @return void 
    */ 
    public function __construct($wantsheet_products) 
    { 
//$wantsheet_products is a standard eloquent model collection, e.g. i get it like this: WantsheetProduct::orderByRaw(self::WANTSHEET_PRODUCT_ORDER_SQL)->get() 
     $this->wantsheet_products = $wantsheet_products; //is ['a','b','c'] 
    } 


    /** 
    * Build the message. 
    * 
    * @return $this 
    */ 
    public function build() 
    { 

//  $this->wantsheet_products is ['b','a','c']; 
     $subject = 'abc'; 
     return $this->from('[email protected]')->view('email.wantsheet.email_wantsheet_to_supplier', [])->subject($subject); 
    } 
} 

編輯續之間的變化情況。 現在,當我做

WantsheetProduct::orderByRaw(EmailService::WANTSHEET_PRODUCT_ORDER_SQL)->get()->toArray();

它不會破壞任何再排序(所以它的工作原理)。但這很愚蠢,不是嗎?

+0

我猜這是一個集合保存問題。基本上,如果你改變順序而不關心鍵名,你還需要明確地告訴集合你已經改變了鍵的順序,以防需要將鍵傳遞給別的東西。嘗試' - > get() - > values();' –

+0

@JoelHinz在將對象交給構造函數之前調用' - > values()'似乎並不能解決問題,'$ this-> wantsheet_products-> values( )'按照他們應該的方式來對待他們 – Toskan

+0

是的,我不確定,所以我只是把它寫成評論。值得一試。希望別人能給你正確的答案! –

回答

1

當您的郵件對象排隊等待發送時,需要您的CollectionModel實例,獲取它們的ID,並將ID列表存儲在排隊作業中。當排隊的作業被處理後,它將採用這些Model ID,並從數據庫中檢索數據。

然而,問題是運行重建集合的查詢並不關心id的順序。它僅運行帶有id列表的whereIn()聲明。

當您轉換您的Collection toArray()時,一切都奏效,因爲它還將所有模型轉換爲數組。所以,它不再是一個模型集合,而是一個數組數組。這裏沒有發生特殊的序列化,所以數據完全按照您發送的那樣進行。

取回訂單的最簡單方法可能是覆蓋restoreCollection方法,因此您可以將order by子句添加到恢復查詢中。這種方法添加到您的WantsheetToSuppliersMail類:

protected function restoreCollection($value) 
{ 
    if (! $value->class || count($value->id) === 0) { 
     return new EloquentCollection; 
    } 

    $model = new $value->class; 

    return $model->newQuery()->useWritePdo() 
     ->whereIn($model->getKeyName(), $value->id) 
     ->orderByRaw(EmailService::WANTSHEET_PRODUCT_ORDER_SQL) 
     ->get(); 
} 

這是與當前功能,只需您的自定義爲了通過已經應用到查詢。

+0

這很有趣....但是這不是一個錯誤嗎?我的意思是一個值得報告的bug?你的解決方案看起來也不是很簡單,試着向那些不知道我們爲什麼在那裏的人解釋代碼。我最終做的是從構造函數中移除$ wantsheet_products,並在'build(){}'函數中重建它,例如'build(){$ wantsheet_products = WantsheetProduct :: orderByRaw(EmailService :: WANTSHEET_PRODUCT_ORDER_SQL) - > get();'但這意味着每個電子郵件的SQL!這是沒有任何開銷的,僅僅因爲它們搞砸了訂單 – Toskan

+0

@Toskan當你序列化雄辯的模型時,每個電子郵件總會有一個查詢,因爲當處理作業時,電子郵件需要重建模型。如果這是一個問題,您可能需要查看是否可以使用將模型轉換爲數組並將該數據傳遞到郵件對象的原始解決方法。 – patricus

+0

所以當我說,不排隊他們,但同步發送他們,我不會面對這個問題?例如而不是' - > queue()'我使用' - > send()',即郵件不會被序列化? – Toskan

0

這是一個已知的laravel 5.3的缺陷

基本上是重新檢索構建函數中的對象,例如,

public function build() 
{ 

    $this->wantsheet_products = WantsheetProduct::orderByRaw(EmailService::WANTSHEET_PRODUCT_ORDER_SQL)->get(); 
    $subject = 'abc'; 
    return $this->from('[email protected]')->view('email.wantsheet.email_wantsheet_to_supplier', [])->subject($subject); 
}