2016-06-21 84 views
4

我最近開始使用Laravel進行開發,而我的第一個項目是一個車輛預訂應用程序。Laravel雄辯多欄IN條款

我似乎做得很好,但我被卡住試圖顯示當前預訂使用雄辯。

該系統的工作原理是將車輛添加到vehicles表中,並將員工添加到employees表中。與數據透視表的多對多關係使用employee_vehicle創建。

員工

+------------+-------------+------+-----+---------+----------------+ 
| Field  | Type  | Null | Key | Default | Extra   | 
+------------+-------------+------+-----+---------+----------------+ 
| id   | int(10)  | NO | PRI | NULL | auto_increment | 
| first_name | varchar(50) | NO |  | NULL |    | 
| surname | varchar(50) | NO |  | NULL |    | 
+------------+-------------+------+-----+---------+----------------+ 

車輛

+--------------+-------------+------+-----+---------+----------------+ 
| Field  | Type  | Null | Key | Default | Extra   | 
+--------------+-------------+------+-----+---------+----------------+ 
| id   | int(10)  | NO | PRI | NULL | auto_increment | 
| registration | varchar(10) | NO |  | NULL |    | 
| make   | varchar(50) | NO |  | NULL |    | 
| model  | varchar(50) | NO |  | NULL |    | 
+--------------+-------------+------+-----+---------+----------------+ 

employee_vehicle

+-------------+------------+------+-----+---------+----------------+ 
| Field  | Type  | Null | Key | Default | Extra   | 
+-------------+------------+------+-----+---------+----------------+ 
| id   | int(10) | NO | PRI | NULL | auto_increment | 
| employee_id | int(10) | NO |  | NULL |    | 
| vehicle_id | int(10) | NO |  | NULL |    | 
| direction | varchar(3) | NO |  | NULL |    | 
| date_booked | datetime | NO |  | NULL |    | 
| damaged  | tinyint(1) | NO |  | NULL |    | 
| mileage  | int(10) | NO |  | NULL |    | 
+-------------+------------+------+-----+---------+----------------+ 

結果

+----+-------------+------------+-----------+---------------------+---------+---------+ 
| id | employee_id | vehicle_id | direction | date_booked   | damaged | mileage | 
+----+-------------+------------+-----------+---------------------+---------+---------+ 
| 1 |   1 |   1 | OUT  | 2016-06-13 09:08:08 |  0 | 2357 | 
| 2 |   1 |   1 | IN  | 2016-06-16 16:29:26 |  0 | 2401 | 
| 3 |   2 |   1 | OUT  | 2016-06-20 10:47:28 |  0 | 2470 | 
| 4 |   3 |   2 | OUT  | 2016-06-14 09:18:52 |  0 | 1403 | 
+----+-------------+------------+-----------+---------------------+---------+---------+ 

這些表有VehicleEmployee模型擴展侃侃而談。這些方法有belongsToMany

我想要做的是獲得Vehicle集合,並熱切地加載員工。這樣,我可以顯示目前預訂的車輛以及目前預訂的車輛。

例如:

$vehicleBookings = Vehicle::with(['employees'])->get();

,我會解釋,一個預訂的工作方式......

基本上,車輛和僱員使用數據透視表連接在一起。該表還記錄預訂日期,預訂方向(例如預訂IN或OUT)以及有關其狀況的附加數據等。

重要的是IN和OUT都有條目,以便在那裏是預訂前後車輛狀況的審計日誌。

我遇到的問題是能夠從可用預訂中獲得車輛的最新狀態,以確定它目前是否已預訂或可供預訂。這決定了車輛可以做什麼。

一些研究,我想出了以下查詢後:

SELECT * 
FROM `employee_vehicle` 
WHERE (`vehicle_id`, `date_booked`) IN (
    SELECT `vehicle_id`, MAX(`date_booked`) 
    FROM `employee_vehicle` 
    GROUP BY `vehicle_id` 
) 

(我甚至不知道這是可能使用多列與IN子句到現在爲止,但它是偉大的!)。

這給了我:

+----+-------------+------------+-----------+---------------------+---------+---------+ 
| id | employee_id | vehicle_id | direction | date_booked   | damaged | mileage | 
+----+-------------+------------+-----------+---------------------+---------+---------+ 
| 3 |   2 |   1 | OUT  | 2016-06-20 10:47:28 |  0 | 2470 | 
| 4 |   3 |   2 | OUT  | 2016-06-14 09:18:52 |  0 | 1403 | 
+----+-------------+------------+-----------+---------------------+---------+---------+ 

這給了我每一個曾經被預訂車輛一行(這是加入任何員工之前)。

但是現在我真的被卡住了。我只是無法弄清楚如何使用Eloquent來編寫一個同樣的查詢,這個查詢也加入了Employees。 (它也需要只顯示車輛當前「OUT」,但我想這是微不足道的一部分!)

可以只寫使用DB::raw('...')查詢,並沒有手動介意寫長的SQL查詢,但我真的想給它一個正確的,嘗試使用雄辯。

我注意到whereIn方法,但它只接受一個字符串作爲一個列名而不是多列數組,所以這是一個不可行的方法。 (除非我錯過了某些東西,或者它計劃將來的Laravel版本?)

我從來沒有真正的框架迷,並且需要一些令人信服的,不希望被打敗,一直堅持與Laravel。這讓我感到沮喪,因爲我覺得只是爲了不弄亂Eloquent會更快。如果我能得到這個工作,那麼我會更加接受它。

+0

那麼你在尋找員工和車輛在一起的employee_vehicle? – num8er

+0

簡短的回答是肯定的。長答案是肯定的,但是我怎麼寫我發佈的查詢_but_使用Eloquent,_also_將所有東西都放在一起。我不知道我是否正確地解釋自己。 – jren207

回答

0

比方說,你已經

員工型號:

class Employee extends Model { 
    protected $table = 'employees'; 
    public $timestamps = false; 
} 

和車型:

class Vehicle extends Model { 
    protected $table = 'employees'; 
    public $timestamps = false; 
} 

,你想通過vehicle_id分組最新日誌。

所以,做一個模型:

class EmployeeVehicle extends Model { 
    protected $table = 'employee_vehicle'; 
    public $timestamps = false; 

    public function employee() { 
    return $this->belongsTo('App\Employee'); 
    } 

    public function vehicle() { 
    return $this->belongsTo('App\Vehicle'); 
    } 
} 

和您請求DB將是這樣的:

$EmployeeVehicles = EmployeeVehicle::with(['employee', 'vehicle']) 
            ->where('date_booked', '>', date('Y-m-d H:i:s', (time() - 3*30*24*60*60))) 
            ->groupBy('vehicle_id') 
            ->selectRaw('*, MAX(`date_booked`) AS `last_date_booked`') 
            ->paginate(50); 

附:我已經添加了where('date_booked', '>', date('Y-m-d H:i:s', (time() - 3*30*24*60*60)),因爲您的查詢數據庫日誌對於數據庫引擎來說是非常繁重的工作,通常最好有過去3個月的數據來確保性能安全。

並嘗試分頁,而不是一切。

+0

啊,所以有可能將一個數據透視表製作成一個模型本身?這是標準/可接受的方式嗎?我都很新:)。 – jren207

+0

當然可以!雄辯是強大的。如果你覺得有點不同(Eloquentish方式)(: – num8er

+0

)Bor me數據透視表是帶有2個字段的表,沒有id字段:employee_id,vehicle_id和數據透視表也可以用作模型,但請記住,您向我們顯示的employee_vehicle是不是數據透視表,它更像是一個「日誌」表(: – num8er