iT邦幫忙

0

laravel eloquent relationship 一問

  • 分享至 

  • twitterImage

大家好,

我create了user , dept 兩個table
下面是兩個model:

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Traits\HasRoles;

use Laravel\Passport\HasApiTokens;

class User extends Authenticatable
{

	//use AuthenticableTrait;
    //
	use HasRoles;
	use HasApiTokens; 
	
	public $table = "user";
	
	protected $keyType = 'string';
	
	public $timestamps = false;
	
	protected $fillable = [
		'id', 'email', 'name_en', 'name_tc',
		'name_zh', 'role_id', 'dept_id', 
		'shop_id', 'remember_token', 'created_at', 'updated_at'
	];
	
	protected $hidden = [
		'password', 'remember_token'
	];
	
	public function getNameEnAttribute($value)
    {
        return $value;
    }
	
	public function setNameEnAttribute($value)
    {
        $this->attributes['name_en'] = "username_en";
    }
	
	public function role()
    {
        return $this->hasOne('App\Roles', 'id');
    }
	
	public function shop()
    {
        return $this->hasOne('App\Shop', 'id');
    }
	
	public function dept()
    {
        return $this->hasOne('App\Dept', 'id', 'dept_id');
    }
	
	public function orderitem()
    {
        return $this->hasMany('App\OrderItem', 'id');
    }
	
	/* return $this->belongsToMany('App\role'); */
	
}
namespace App;

use Illuminate\Database\Eloquent\Model;

class Dept extends Model
{
    //
	protected $table = "dept";
	
	protected $fillable = [
		'id', 'name_en', 'name_tc', 'name_zh', 
		'created_at', 'updated_at'
	];
	
	public function user()
    {
		// set back many to one relationship with user model
        return $this->hasOne('App\Dept', 'user_dept_id', 'dept_id');
    }
	
	public function role()
    {
        return $this->hasMany('App\Item');
    }
}

不知道設定得有沒有錯
user 和 dept 的relationship 是 user hasone department, department hasMany user

但是當我用這句
User::with('dept')->where("id", Auth::user()->id)->get();

返回的json 是這樣...
{"status":"success","data":[{"id":"1","email":"admin@tuta.pos","name_en":"admin","name_tc":"\u7ba1\u7406\u54e1","name_zh":"\u7ba1\u7406\u54e1","role_id":"1","dept_id":"k02","shop_id":"1","created_at":"2020-07-14 07:23:58","updated_at":"2020-07-14 07:23:58","dept":null}]}

dept 出了null, 請問是我的user-dept 的關係錯嗎?

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

0

出了null代表沒關聯資料。
你得先確定你的 dept 表中的id有「k02」才行。
畢竟你的dept_id是=k02
你這段

public function dept()
    {
        return $this->hasOne('App\Dept', 'id', 'dept_id');
    }

是代表用user的dept_id去關聯你的dept表的id

且你在dept的model,反向user也錯了, 因該要如下才對

function user(){
        return $this->belongsTo('App\User', 'id', 'dept_id');
    }
看更多先前的回應...收起先前的回應...
diu7me iT邦新手 4 級 ‧ 2020-07-16 18:55:20 檢舉

謝謝你的幫忙, 但是我改了之後, 用這句call
return response()->json([ 'status' => 'success', 'data' => User::where('id', Auth::user()->id)->first()->dept ], 200);

只出了
{"status":"success","data":{"id":0,"name_en":"bartender","name_tc":"\u6c34\u5427","name_zh":"\u6c34\u5427"}}

沒有了user model 的data. 不知道為何?

你再加強一下吧。
你資料只取 dept 。當然就只有 dept 的資料啊。

其實你這邊有點搞混一個東西了。

你知道你的auth其實就是你的user表了嘛?
為何還要再多做一個搜尋uid幹嘛??
不覺得很多餘??

orm的觀念還需要再加強一下。不要將其當db操作。
它是一種容器的觀念。

diu7me iT邦新手 4 級 ‧ 2020-07-17 11:03:07 檢舉

先謝謝你的回答, 但我真的找了很久, 真的不知道這句怎寫才能
也拿到user

User::where('id', Auth::user()->id)->first()->dept

diu7me iT邦新手 4 級 ‧ 2020-07-17 11:10:29 檢舉

你知道你的auth其實就是你的user表了嘛?
為何還要再多做一個搜尋uid幹嘛??
不覺得很多餘??

這句我真的知道, 但我不知道怎樣可以用auth寫成Auth::user()->dept ??這樣

diu7me iT邦新手 4 級 ‧ 2020-07-17 11:17:47 檢舉

我只是想可以返回一個json
是 user 是 Auth::user()->id 而且dept_id 是k02

diu7me iT邦新手 4 級 ‧ 2020-07-17 11:27:24 檢舉

但是當我這樣寫 var_dump(Auth::user()->dept); die;

lluminate\Database\QueryException: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'dept.dept_id' in 'where clause' (SQL: select * from dept where dept.dept_id = 1 and dept.dept_id is not null limit 1) in file C:\wamptemppos1\www\resPos\vendor\laravel\framework\src\Illuminate\Database\Connection.php on line 664

因為dept_id 是user table 而不是dept, 那正確的是怎樣寫才能把user 和 所屬的dept_id同返回在一個json, 已經花了一天找, 好難...謝謝.

diu7me iT邦新手 4 級 ‧ 2020-07-17 11:42:28 檢舉

Auth::user()->dept->load('user')->toJson()
寫成這樣也不行

$userDb = Auth::with(['dept'])->user();

加油,我一開始玩orm也是這樣。搞懂之後就覺得很簡單了。
你現在還沒搞懂容器觀念。才會搞不懂。

diu7me iT邦新手 4 級 ‧ 2020-07-17 12:10:33 檢舉

BadMethodCallException
Method Illuminate\Auth\SessionGuard::with does not exist.

diu7me iT邦新手 4 級 ‧ 2020-07-17 12:22:10 檢舉

試過這樣寫
var_dump(User::with(['dept' => function ($query) {
$query->where('id', '=', Auth::user()->dept_id);
}])->get()); die;

也是出了
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'dept.dept_id' in 'where clause' (SQL: select * from dept where dept.dept_id in (1) and id = k02)

diu7me iT邦新手 4 級 ‧ 2020-07-17 12:50:21 檢舉

https://ithelp.ithome.com.tw/upload/images/20200717/20122930lNmhnoYJN6.png

因為是user 的dept_id 對應 dept 的 id, 我在user table 已經幫dept_id 加了foreign key, 那dept 的id 也要加嗎?

你的user模組內至先要有

public function dept()
    {
        return $this->hasOne('App\Dept', 'id', 'dept_id');
    }

然後你先試試如下的用法

$userDb = Auth::user();
$userDb = $userDb->dept();
dd($userDb->toArray());

先自已查看你取到什麼值了。

這樣子說好了,你原本的做法及後面的做法,都是所謂的「自體循環」做法。
你的資料在你原本的容器都已經有了。
但你自已還用容器去請求一個新的容器資料。
這不是多此一舉嘛?

0
Victor
iT邦新手 2 級 ‧ 2020-07-17 09:09:10

修改 User Model dept()

public function dept()
{
    // 先外鍵 再 主鍵
    return $this->hasOne('App\Dept', 'dept_id', 'id');
}

再使用

User::with('dept')->where("id", Auth::user()->id)->get();

但照理來說,主要功能是找出登入的帳號的資料,並包含 dept資料,User id 應該只有一位,請使用一下任一方法替代。

User::with('dept')->where("id", auth()->user()->id)->first();

User::with('dept')->find(auth()->user()->id);.

auth()->user()->load('dept');

還有很多寫法...

JSON 原本

{
    "status": "success",
    "data": [
        {
            "id": "1",
            "email": "admin@tuta.pos",
            "name_en": "admin",
            "name_tc": "\u7ba1\u7406\u54e1",
            "name_zh": "\u7ba1\u7406\u54e1",
            "role_id": "1",
            "dept_id": "k02",
            "shop_id": "1",
            "created_at": "2020-07-14 07:23:58",
            "updated_at": "2020-07-14 07:23:58",
            "dept": null
        }
    ]
}

建議這樣比較合理,不過還是看你的專案實際狀況。

{
    "status": "success",
    "data": {
        "id": "1",
        "email": "admin@tuta.pos",
        "name_en": "admin",
        "name_tc": "\u7ba1\u7406\u54e1",
        "name_zh": "\u7ba1\u7406\u54e1",
        "role_id": "1",
        "dept_id": "k02",
        "shop_id": "1",
        "created_at": "2020-07-14 07:23:58",
        "updated_at": "2020-07-14 07:23:58",
        "dept": null
    }
}
diu7me iT邦新手 4 級 ‧ 2020-07-17 11:37:04 檢舉

victor 你好,
我已經用了Auth::user()->load('dept')

但是在postman 出了這樣
Illuminate\Database\QueryException: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'dept.dept_id' in 'where clause' (SQL: select * from dept where dept.dept_id in (1)) in file C:\wamptemppos1\www\resPos\vendor\laravel\framework\src\Illuminate\Database\Connection.php on line 664

都是拿了dept, 而沒有了user....是怎樣寫, 找了好久, 好痛苦

diu7me iT邦新手 4 級 ‧ 2020-07-17 11:42:37 檢舉

Auth::user()->dept->load('user')->toJson()
寫成這樣也不行

Victor iT邦新手 2 級 ‧ 2020-07-17 13:37:01 檢舉

你有修改這個嗎?
User Model 的 dept() 先外鍵 再 主鍵 如下所示

public function dept()
{
    return $this->hasOne('App\Dept', 'dept_id', 'id');
}

我要發表回答

立即登入回答