การตรวจสอบความถูกต้องล้มเหลวในข้อจำกัดเฉพาะ

ฉันกำลังตรวจสอบแบบฟอร์มอย่างง่ายโดยใช้ Validator คลาสของ Laravel

ในโมเดลผู้ใช้ของฉัน ฉันสร้างฟังก์ชันนี้เพื่อส่งคืนอาร์เรย์ที่มีกฎการตรวจสอบ:

/** function to return the rules to validate a user */
    public static function rules($email = null, $username = null) {
        return array(
            "name" => "required",
            "username" => "required|unique:user,username" . ($username ? ",'$username',username" : ""),
            "email" => "required|email|unique:user,email" . ($email ? ",'$email',email" : ""),
        );
    }

ฉันใช้ RESTful Controller ดังนั้นเมื่อฉันดำเนินการเมธอด update() ฉันจะตรวจสอบข้อมูลแบบฟอร์มด้วยอาร์เรย์ด้านบน

นี่คืออาร์เรย์ของฉันหลังจากการทำงานของฟังก์ชันกฎ:

array (size=3)
  'name' => string 'required' (length=8)
  'username' => string 'required|unique:user,username,'vitorluis',username' (length=50)
  'email' => string 'required|email|unique:user,email,'[email protected]',email' (length=63)

ฉันกำลังบอกให้ Laravel เพิกเฉยต่ออีเมลและชื่อผู้ใช้นี้ แต่เครื่องมือตรวจสอบความถูกต้องล้มเหลว โดยบอกว่าชื่อผู้ใช้และอีเมลที่ระบุมีอยู่แล้ว

ฉันกำลังทำอะไรผิดเหรอ?


person Vitor Villar    schedule 07.03.2015    source แหล่งที่มา


คำตอบ (1)


คุณเข้าใจผิดว่าพารามิเตอร์ id เป็นกฎ unique นิดหน่อย คุณต้องส่งรหัสของเรกคอร์ดที่คุณกำลังอัปเดต จากนั้นแจ้งกฎเฉพาะให้ยกเว้นรหัสเรกคอร์ดนั้น

// $id should be the string 'NULL' if no id passed in
public static function rules($id = 'NULL') {
    return array(
        "name" => "required",
        "username" => "required|unique:user,username,".$id.",id_user",
        "email" => "required|email|unique:user,email,".$id.",id_user",
    );
}

คำอธิบาย

สำหรับการใช้งานที่มีอยู่ หากคุณดูบันทึกการสืบค้น (DB::getQueryLog()) คุณจะเห็นว่าคำสั่งที่เรียกใช้สำหรับการตรวจสอบชื่อของคุณจะเป็น:

select count(*) as aggregate from `user` where `username` = 'vitorluis' and `username` <> '\'vitorluis\''

แบบสอบถามนี้จะส่งกลับ 1 ซึ่งหมายความว่าพบระเบียนและข้อมูลใหม่ไม่ซ้ำกัน (ไม่ผ่านการตรวจสอบที่ไม่ซ้ำกัน)

หากคุณต้องแก้ไขปัญหาเดียวด้วยการอ้างอิงค่าที่ส่งไปยังกฎ คำค้นหาของคุณจะกลายเป็น:

select count(*) as aggregate from `user` where `username` = 'vitorluis' and `username` <> 'vitorluis'

แน่นอนว่าข้อความค้นหานี้จะส่งกลับค่า 0 เสมอ ดังนั้นไม่ว่าคุณจะเปลี่ยนชื่อผู้ใช้เป็นค่าใดก็ตาม คำค้นหาก็จะผ่านกฎเฉพาะเสมอ

สิ่งที่คุณต้องการทำจริงๆ คือตรวจสอบให้แน่ใจว่าชื่อผู้ใช้ที่คุณกำหนดนั้นไม่ซ้ำกันในทุกเรกคอร์ด ยกเว้นเรกคอร์ดเดียวที่คุณกำลังอัปเดตอยู่ ในการดำเนินการนี้ คุณจะต้องส่งรหัสของเรกคอร์ดที่คุณกำลังอัปเดตไปยังกฎการตรวจสอบ เพื่อให้สามารถสร้างแบบสอบถามที่ถูกต้องได้ สมมติว่าคุณกำลังอัปเดตบันทึกด้วยรหัส 10:

select count(*) as aggregate from `user` where `username` = 'vitorluis' and `id_user` <> 10

แก้ไข

แก้ไขเนื่องจากความคิดเห็น

หากฟิลด์ id ไม่ใช่ id คุณสามารถระบุฟิลด์ id ได้โดยใช้พารามิเตอร์ที่สี่ให้กับกฎเฉพาะ ฉันได้อัปเดตโค้ดด้านบนเพื่อใช้ชื่อฟิลด์ ID ของคุณ id_user

ดูเอกสารประกอบของ Laravel สำหรับกฎเฉพาะได้ที่นี่

person patricus    schedule 07.03.2015
comment
ใช่ แพทริคัส แต่คีย์หลักของฉันไม่ใช่ id แต่เป็น id_user ฉันจะพูดอย่างนั้นในกฎอาร์เรย์ได้อย่างไร ฉันกำลังบอกคุณเรื่องนี้เพราะ Laravel ส่งข้อผิดพลาดนี้: Undefined column: 7 ERROR: column "id" does not exist - person Vitor Villar; 07.03.2015
comment
@VitorLuis หากคุณเป็นคีย์หลักที่แตกต่างจาก id คุณสามารถส่งผ่านได้หลังจากค่า ID ในกรณีนี้: "username" => "required|unique:user,username,".$id.",id_user" - person Bogdan; 07.03.2015