iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 9
0
Modern Web

React.js & Laravel 30天訓練系列 第 9

【Day 9】A Part2 of implementation of Service in Laravel

今天還是在 Laravel 裡面

因為今天遇到了個難題 卡住了一陣子

不過這也沒有什麼不好 我以前一直就很希望 不要大家都是教學 而是有人真的出來說他做什麼東西
然後 怎樣過關的比較重要 不然就像很多網站 其實解法只有一套 然後大家都只是複製來貼上的

OK 那我今天遇到什麼樣的問題呢

簡單解釋一下我要撈出來的資料是這樣的

MyBox 我的信箱
裡面要放所有與我個人有關的主題
所以她牽連的表很多

今天我在弄要把他的建立人資料拉出來 卡住了

簡單說 如果我只有一個Key 對 一個Key
Laravel 你可以用 hasOne 去完成這樣的資料連結

例如我的 MyBox 都會與一個主題 相關聯
so

<?php

namespace App\Http\Models;

use Illuminate\Database\Eloquent\Model;

class MyBox extends Model
{
	// 注意預設上,在資料表裡需要有  updated_at 和 created_at 兩個欄位。如果你不想設定或自動更新這兩個欄位,將類別裡的  $timestamps 屬性設為 false。
    public $timestamps = false;

    public function __construct()
    {
	    // 指定告訴Laravel 要對應哪一個Table
    	$this->setTable("MyBox");
    }
    // MyBox 拉出 Subject
    public function SubjectData()
    {
    	// 舊的 SP 有拉出一個DataType 主要是在判斷 0->未讀紀錄 1->已讀紀錄 2->申請歸檔
    	return $this
    		-> hasOne('App\Http\Models\Subject', 'SubjID', 'SubjID')
    		-> select('ApplyCloseBy', 'ApplyCloseOn', 'CloseDays', 'ClosedOn', 'CompID', 'CreatedBy', 'CreatedOn', 'CusTagId', 'DiscID', 'IsActive', 'ModifiedBy', 'ModifiedOn', 'PlanCloseOn', 'PlanDiff', 'Progress', 'ReplyCount', 'SubjID', 'SubjTagId', 'Title')
    		;
    }

MyBox 的Model 裡面我就會去寫一個SubjectData的方法
然後,把下面的程式碼放到 service or 你想直接在controller 也是OK

$myboxData = MyBox::with('SubjectData')
                ->whereRaw("CompID = '".$_compid."' and UserID = '".$_userid."'")
                ->get();

然後你用PostMan去繞一下 你就會看到類似這樣的資料
https://ithelp.ithome.com.tw/upload/images/20171227/2010776740FjRJ59OS.png

簡單說就是 Mybox 為主 你with進來的 要依附在他下面當作一個物件

好,這只是一個很無聊的引述,再來才是我卡住的地方
我要用 MyBox Table 裡面的 CreatedBy & CompID 去對應 CompUser Table 的 UserID & CompID
但是我繞了很久 也有問寫一段時間的Laravel 開發者 答案是???

所以我最後覺得 hasOne、hasMany 他應該本來的設計就是只有一個KEY
你如果要有其他的作為 應該是要有像where的方法

所以我是這樣寫的 先看我在Model裡面設定的關聯 CreatorUser

public function CreatorUser()
{
    return $this
        -> hasMany('App\Http\Models\CompUser', 'UserID', 'CreatedBy')
        -> select ('CompID', 'UserID', 'LastName', 'FirstName');
}

在來是重點,首先 你要先用一個陣列包住你要with的,雖然是我亂試的,不過成功就代表想法是很OK的
然後你要針對陣列裡面你的那一個with做 吃過濾方法的動作 =>function($query)...
然後,像我是要把 service 接收到的參數放進去過濾
所以,我還要多一個 use (你方法傳進來的參數)
這樣你才可以把它放到 $query->where(...)這裡面

$myboxData = MyBox::with(['SubjectData', 'CreatorUser' => function($query) use ($_compid){
                        $query->where('CompID', '=', $_compid);
                    }])
                    ->whereRaw("CompID = '".$_compid."' and UserID = '".$_userid."'")
                    ->get();

話不多說 來做一下前後比較,首先,是沒有用我想到的方法之前的版本
簡單說 會無法過濾掉這間公司才該出現的人
https://ithelp.ithome.com.tw/upload/images/20171227/20107767G66lmcAfoM.png

用了之後呢~ 就只會產生出一筆 代表我們的過濾 是非常OK的
https://ithelp.ithome.com.tw/upload/images/20171227/20107767ChD8SKKyqD.png

這裡我要寫下幾個我用來搜尋方法 但是卻找不到好方法的關鍵字
laravel hasone/hasmany multiple columns
laravel hasone/hasmany mutiple key

今天又突破一個點了 明天繼續!


上一篇
【Day 8】A Part of implementation of Service in Laravel
下一篇
【Day 10】A Part3 of implementation of Service in Laravel
系列文
React.js & Laravel 30天訓練30

尚未有邦友留言

立即登入留言