Menu

Monday, August 5, 2019

[Laravel - Model] ข้อควรระวังของการใช้ฟังก์ชั่น where และ orWhere ของ Laravel Model
[Laravel - Model] Warning: Using where and orWhere functions of Laravel Model

สมมติว่า
  • OrganizationChildren เป็น Laravel model ที่ผูกกับตาราง organization_children ในฐานข้อมูล
  • OrganizationChildren ประกอบด้วยฟิลด์ parent_organization_id และ child_organization_id 
  • $org1->id และ $org2->id เป็นค่า id ของ Organization โดยมีค่าเป็น 1 และ 2 ตามลำดับ

ถ้าเราต้องการ query ข้อมูล โดยใช้ SQL ดังนี้
select * 
from `organization_children` 
where (`parent_organization_id` = 1 and `child_organization_id` = 2) or 
(`parent_organization_id` = 2 and `child_organization_id` = 1)
เราอาจจะเขียนโค้ดตามข้างล่างนี้
$orgChild = OrganizationChildren::where([
    'parent_organization_id' => $org1->id,
    'child_organization_id' => $org2->id
])->orWhere([
    'parent_organization_id' => $org2->id,
    'child_organization_id' => $org1->id,
])->first();
แต่เมื่อเราลองให้พิมพ์ SQL statement ที่ได้ตามโค้ดข้างบน จะได้
select * 
from `organization_children` 
where (`parent_organization_id` = 1 and `child_organization_id` = 2) or 
(`parent_organization_id` = 2 or `child_organization_id` = 1) limit 1
จะเห็นได้ว่า statement ใน array ของ orWhere มีการเชื่อมกันด้วย or ซึ่งไม่ตรงกับสิ่งที่เราต้องการ

ดังนั้น เราจำเป็นต้องเปลี่ยนโค้ดเป็นตามข้างล่างนี้
$orgChild = OrganizationChildren::where([
    'parent_organization_id' => $org1->id,
    'child_organization_id' => $org2->id,
])->orWhere(function ($q) use ($data, $organization) {
    $q->where([
        'parent_organization_id' => $org2->id,
        'child_organization_id' => $org1->id,
    ]);
})->first();
เมื่อเราลองให้พิมพ์ SQL statement ที่ได้ตามโค้ดข้างบน จะได้
select * 
from `organization_children` 
where (`parent_organization_id` = 1 and `child_organization_id` = 2) or 
((`parent_organization_id` = 2 and `child_organization_id` = 1)) limit 1

สังเกตว่า ตัวเชื่อมที่ใช้ในการเชื่อมกับ statement ก่อนหน้าและตัวเชื่อมที่ใช้เชื่อมระหว่าง statement ภายใน array ของทั้ง 2 functions เป็นดังนี้
  • where ใช้ and เป็นตัวเชื่อมทั้งสองกรณี
  • orWhere ใช้ or เป็นตัวเชื่อมทั้งสองกรณี

No comments:

Post a Comment