2014-04-15 15 views
14

Tôi có hai Bộ sưu tập và tôi muốn hợp nhất nó với một biến (tất nhiên, với thứ tự của một collumn - created_at). Làm thế nào tôi có thể làm điều đó?Hợp nhất và Sắp xếp hai Bộ sưu tập Eloquent?

điều khiển của tôi trông rằng:

$replies = Ticket::with('replies', 'replies.user')->find($id); 
$logs = DB::table('logs_ticket') 
     ->join('users', 'users.id', '=', 'mod_id') 
     ->where('ticket_id', '=', $id) 
     ->select('users.username', 'logs_ticket.created_at', 'action') 
     ->get(); 

Output của tôi trông ví dụ:

Trả lời:

ID | ticket_id | username | message | created_at 
1 | 1   | somebody | asdfghj | 2014-04-12 12:12:12 
2 | 1   | somebody | qwertyi | 2014-04-14 12:11:10 

Logs:

ID | ticket_id | username | action | created_at 
1 | 1   | somebody | close | 2014-04-13 12:12:14 
2 | 1   | somebody | open | 2014-04-14 14:15:10 

Và tôi muốn một cái gì đó như thế này :

ticket_id | table | username | message | created_at 
1   |replies| somebody | asdfghj | 2014-04-12 12:12:12 
1   | logs | somebody | close | 2014-04-13 12:12:14 
1   | logs | somebody | open | 2014-04-14 11:15:10 
1   |replies| somebody | qwertyi | 2014-04-14 12:11:10 

EDIT:

mẫu vé của tôi trông rằng:

<?php 

class Ticket extends Eloquent { 

    protected $table = 'tickets'; 

    public function replies() { 
     return $this->hasMany('TicketReply')->orderBy('ticketreplies.created_at', 'desc'); 
    } 

    public function user() 
    { 
     return $this->belongsTo('User'); 
    } 
} 
?> 
+0

DB :: bảng trả về mảng của stdObjects do đó kết quả sẽ không nhất quán hoặc sẽ cần chuyển đổi sang Bộ sưu tập/Mô hình Eloquent.Dán các mô hình của bạn với các mối quan hệ để có được câu trả lời của bạn một cách tốt hơn –

+0

@deczo Tôi đã thêm mô hình Vé. – Siper

+0

Còn nhật ký thì sao? –

Trả lời

19

Bạn sẽ không thể nhận được chính xác những gì bạn muốn một cách dễ dàng.

Nói chung, việc hợp nhất phải dễ dàng với $collection->merge($otherCollection); và sắp xếp với $collection->sort();. Tuy nhiên, hợp nhất sẽ không hoạt động theo cách bạn muốn nó do không có ID duy nhất và cột 'bảng' mà bạn muốn, bạn sẽ phải thực hiện theo cách thủ công.

Ngoài ra họ đang thực sự cả hai sẽ trở thành bộ sưu tập các loại khác nhau Tôi nghĩ (một trong những được dựa trên một Eloquent\Model sẽ Eloquent\Collection, và người kia là một tiêu chuẩn Collection), mà có thể gây ra các vấn đề riêng của mình. Như vậy, tôi khuyên bạn nên sử dụng DB :: table() cho cả hai, và tăng thêm kết quả của bạn với các cột bạn có thể kiểm soát.

Đối với mã để đạt được điều đó, tôi không chắc chắn vì tôi không làm rất nhiều công việc DB cấp thấp trong Laravel, vì vậy không biết cách tốt nhất để tạo các truy vấn. Dù bằng cách nào, chỉ vì nó trông giống như bắt đầu là một nỗi đau để quản lý điều này với hai truy vấn và một số hợp nhất PHP, tôi muốn đề nghị làm tất cả trong một truy vấn DB. Nó thực sự sẽ xem xét gọn gàng và có lẽ là dễ bảo trì hơn:

SQL bạn sẽ cần phải là một cái gì đó như thế này:

SELECT * FROM 
(
    SELECT 
     `r`.`ticket_id`, 
     'replies' AS `table`, 
     `u`.`username`, 
     `r`.`message`, 
     `r`.`created_at` 
    FROM `replies` AS `r` 
    LEFT JOIN `users` AS `u` 
     ON `r`.`user_id` = `u`.`id` 
    WHERE `r`.`ticket_id` = ? 
) UNION (
    SELECT 
     `l`.`ticket_id`, 
     'logs' AS `table`, 
     `u`.`username`, 
     `l`.`action` AS `message`, 
     `l`.`created_at` 
    FROM `logs` AS `l` 
    LEFT JOIN `users` AS `u` 
     ON `l`.`user_id` = `u`.`id` 
    WHERE `l`.ticket_id` = ? 
) 
ORDER BY `created_at` DESC 

Nó khá tự giải thích: làm hai truy vấn, trở về các cột tương tự, UNION và sau đó sắp xếp kết quả được đặt trong MySQL. Hy vọng rằng nó (hoặc một cái gì đó tương tự, như tôi đã phải đoán cấu trúc cơ sở dữ liệu của bạn) sẽ làm việc cho bạn.

Để dịch nó thành truy vấn kiểu Laravel DB::, tôi đoán điều đó tùy thuộc vào bạn.

18

Một giải pháp nhỏ cho sự cố của bạn.

$posts = collect(Post::onlyTrashed()->get()); 
$comments = collect(Comment::onlyTrashed()->get()); 

$trash = $posts->merge($comments)->sortByDesc('deleted_at'); 

Bằng cách này bạn chỉ có thể hợp nhất chúng, ngay cả khi có ID trùng lặp.

+2

Không hiệu quả, nhưng thực hiện công việc trong một nhúm! – alexw

+0

Tại sao tính năng này hoạt động? Tất cả phương thức collect() thực hiện là tạo một Collection mới? – Robert

+3

Eloquent trả về một 'Eloquent Collection' và thu thập trả về một' Collection' bình thường. Bộ sưu tập 'bình thường' có các phương thức khác nhau, sau đó là 'Bộ sưu tập Eloquent'. –

Các vấn đề liên quan