2016-02-16 17 views
6

Tôi có mối quan hệ đa hình một đến chính xác như được mô tả in documentation, ngoại trừ tôi có phiếu bầu thay vì ảnh và cột bầu chọn số nguyên trong bảng phiếu bầu. Như thế:Laravel 5.2 phạm vi truy vấn về mối quan hệ đa hình

-votes 
--id 
--vote 
--voteable_id 
--voteable_type 

Mô hình Vote có phương pháp voteable:

public function voteable() 
{ 
    return $this->morphTo(); 
} 

Nhưng đối với mô hình mà tôi muốn có phiếu kèm theo (trang trong ví dụ này) Tôi đã tạo ra một VoteableTrait, trong đó có phương thức vote() morphMany và phạm vi tôi đang cố gắng làm việc. Phạm vi sẽ thêm tổng của tất cả các phiếu bầu thuộc về một mô hình nhất định và đặt hàng các mô hình gốc bằng tổng. Phạm vi như tôi đã thử:

public function scopeWithVotesTrait($query) 
{ 
    return $query->with(['votes' => function($q){ 
     $q->select(\DB::raw("SUM(vote) AS votes"), 'voteable_id')->first(); 
    }]); 
} 

Nhưng với điều này tôi không thể orderBởi như Laravel thực hiện 2 truy vấn khác nhau, một cho mô hình mẹ và một cho phiếu bầu dường như. Kết quả của việc trang :: withVotesTrait() -> đầu tiên() đặt phiếu trong một mảng:

{ 
"id": 1, 
    "votes": [ 
    { 
     "votes": "-1", 
     "voteable_id": 1 
    } 
    ] 
} 

Ý tưởng khác tôi đã có được để thực hiện một tham gia thay vì -> với() như thế:

public function scopeWithVotesTrait($query, $model, $table) 
{ 
    return $query->join('votes', function($join) use($model, $table) 
    { 
     $join->on('votes.voteable_id', '=', $table . '.id') 
      ->where('votes.voteable_type', '=', $model); 
    })->select('*', \DB::raw('sum(vote) as votes')) 
    ->orderBy('votes')->groupBy($table . '.id'); 
} 

Nhưng nếu tôi phải đặt thủ công $ model ('App \ ParentModel') và $ table ('parent_models') mỗi khi tôi sử dụng phạm vi, loại nhịp đập đó nhằm mục đích đưa nó vào một đặc điểm.

Vậy có cách nào để sắp xếp hiệu quả theo tổng số phiếu bầu trong ví dụ đầu tiên về phạm vi của tôi không? Hoặc là có bất kỳ phương pháp tĩnh bạn có thể gọi từ Eloquent Model sẽ trả về tên mô hình và một cho mô hình bảng để làm cho ví dụ thứ hai làm việc?

Bất kỳ ý tưởng nào khác về cách tạo phạm vi có thể đính kèm tổng số phiếu bầu vào mô hình và thứ tự gốc của nó?

Trả lời

4

Tôi đã làm cho nó hoạt động với ví dụ thứ hai bằng cách tham gia. Eloquent \ Model có phương thức tĩnh getTable() trả về tên bảng mô hình, vì vậy tôi có thể chuyển nó thành tham số mô hình $ động. Và hàm php get_class() sẽ trả về namespace với classname của mô hình cha cho tham số $ model.

truy vấn chính xác cho những gì tôi muốn đạt được:

public function scopeWithVotesTrait($query) 
{ 
    return $query->leftJoin('votes', function($join) use($model, $table) 
    { 
     $join->on('votes.voteable_id', '=', $table . '.id') 
      ->where('votes.voteable_type', '=', $model); 
    })->addSelect('*', $table . '.id', \DB::raw('COALESCE(SUM(vote),0) as votes')) 
    ->groupBy($table . '.id')->orderBy('votes'); 
} 

Tôi cũng đã thêm liên hiệp, mà sẽ làm cho lợi nhuận truy vấn 0 nếu không có phiếu được tìm thấy. Điều này là để orderBy luôn đúng.

Tôi cũng đã chỉ định * và parent_table.id để chọn các câu lệnh. Nếu không có * truy vấn sẽ chỉ trả lại bất cứ điều gì chúng ta chỉ định trong câu lệnh select. Và không có parent_table.id truy vấn sẽ không trả về bất kỳ mô hình nào chúng ta có thể truy vấn với các phương thức quan hệ (ví dụ: Model :: withVotesTrait() -> với ('some_other_child') sẽ không thêm some_other_child vào kết quả).

Tôi cũng đã sử dụng leftJoin thay vì tham gia để nó sẽ luôn trả về tất cả phụ huynh, bất kể số phiếu bầu liên quan đến nó như thế nào.

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