Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Ruby

จัดเก็บสถานะ UI ชั่วคราวใน Rails ได้อย่างง่ายดายด้วย Kredis

Kredis (Keyed Redis) เป็นการเพิ่มเติมล่าสุดในชุดเครื่องมือของนักพัฒนา Rails มันมุ่งลดความซับซ้อนในการจัดเก็บและเข้าถึงข้อมูลที่มีโครงสร้างบน Redis

ในส่วนแรกของชุด 2 ส่วนนี้ เราจะเริ่มด้วยการเจาะลึกว่า Kredis ทำงานอย่างไร จากนั้นเราจะวิ่งผ่านกรณีการใช้งานตัวอย่างสำหรับการจัดเก็บสถานะ UI ชั่วคราวโดยใช้ Redis key ที่กำหนดเอง

ลองเริ่มกันเถอะ!

บทนำ Kredis สำหรับ Rails

Kredis เป็น Railtie ที่ให้ wrappers ที่สะดวกเพื่อปรับกระบวนการใช้งานใน 3 ด้าน:

  • Ruby-esque API: ตัวอย่างเช่น ประเภทคอลเลกชันอย่าง Kredis.list หรือ Kredis.set จำลองประเภท Ruby แบบดั้งเดิม (และ API ของพวกเขา) มากที่สุด
  • Typings: มีประโยชน์โดยเฉพาะสำหรับคอลเลกชัน Kredis สามารถจัดการ type casting ของ elements จาก/ไปยังประเภทข้อมูลมาตรฐาน (เช่น datetime, json)
  • ActiveRecord DSL: อาจเป็นทรัพย์สินใหญ่ที่สุดของไลบรารี มันช่วยให้คุณเชื่อมโยงโครงสร้างข้อมูล Redis ใดๆ กับ อินสแตนซ์โมเดลเฉพาะ ได้อย่างง่ายดาย

นี่คือตัวอย่างจาก README:

 

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

  • ActiveRecord: ในกรณีส่วนใหญ่ ต้องเพิ่มคอลัมน์หรือ patch โมเดลข้อมูลของคุณ ต้องมี migration รวมถึงการ backfill ระคอร์ดเก่า
  • Session: key/value store เริ่มต้นของทุกแอป Rails และไม่ต้องตั้งค่าหรือตั้งค่าน้อย ข้อเสียคือข้อมูลที่จัดเก็บไว้ไม่รอดชีวิตวงจร login/logout

Kredis นำตัวเลือกที่สามมาเสนอ ต้องการการตั้งค่าน้อยนอกจากการเรียก DSL ในโมเดล แต่หาก instance Redis ของคุณไม่ล้ม ข้อมูลของคุณจะจัดเก็บข้าม sessions และแม้แต่อุปกรณ์ต่างๆ ดังนั้นกรณีการใช้งานที่ดีสำหรับ Kredis คือข้อมูลที่ไม่สำคัญมากที่คุณต้องการแชร์ข้ามขอบเขตอุปกรณ์ เช่นในเว็บแอปและแอปมือถือร่วมทาง

กรณีศึกษา: ทำให้สถานะยุบ/ขยายของ UI คงอยู่และกู้คืนด้วย Kredis

ตัวอย่างทั่วไปของกรณีการใช้งานที่ดีสำหรับ Kredis คือการทำให้สถานะ UI คงอยู่ เช่น:

  • สถานะเปิด/ปิด sidebar
  • สถานะเปิด/ปิด tree view
  • สถานะยุบ/ขยาย accordion
  • เลย์เอาต์แดชบอร์ดที่กำหนดเอง
  • จำนวนบรรทัดของตารางข้อมูลที่จะแสดง

เพื่อการสาธิต เราจะดูวิธีจัดการสถานะยุบ/ขยายของ element <details>

ลองเริ่มด้วยแอป Rails ใหม่ เพิ่ม kredis ใน bundle และรัน installer:

 

หมายเหตุ: นี่จะสร้างไฟล์การกำหนดค่า Redis ใน config/redis/shared.yml

สำหรับส่วนที่เหลือของบทความนี้ ฉันจะสมมติว่าคุณมี instance Redis ท้องถิ่นที่กำลังทำงาน บน macOS ด้วย Homebrew นี่ง่ายเพียงแค่รัน:

 

โปรดดูคู่มือ "Getting Started" อย่างเป็นทางการสำหรับข้อมูลเกี่ยวกับวิธีติดตั้ง Redis บนระบบปฏิบัติการของคุณ

การรับรองตัวตนผู้ใช้

เราจะใช้โมเดล User เป็นเอนทิตีในการจัดเก็บข้อมูลสถานะ UI เพื่อหลีกเลี่ยงการอภิปรายที่ไม่จำเป็นที่นี่ เราจะใช้สิ่งที่ Devise ให้มาตามมาตรฐาน:

 

จากนั้นเราสร้างผู้ใช้ตัวอย่างใน Rails console:

 

แอปตัวอย่างของเรา: ร้านค้าออนไลน์

เพื่อแสดงให้เห็นว่า Kredis ช่วยทำให้สถานะของโครงสร้างต้นไม้ที่ซับซ้อนคงอยู่ได้อย่างไร เราจะทำเป็นว่าเรากำลังดำเนินร้านค้าปลีกออนไลน์ เพื่อสิ่งนี้ เราจะ scaffold โมเดล Department และ Product เรารวม self join จาก department ไป department เพื่อสร้างโครงสร้าง nested สองระดับ:

 

เราต้องอนุญาต null parents ทั้งนี้ เพื่อรองรับรากของต้นไม้ของเรา:

 

โมเดล Department และ Product ของเราถูกกำหนดดังนี้:

 

สุดท้าย เราใช้ faker เพื่อสร้างข้อมูล seed:

 

การสร้าง Storefront แบบ Scaffold

เราจะสร้าง HomeController เรียบง่ายที่จะทำหน้าที่เป็นหน้าร้านของร้านค้าของเรา

 

เราทำ self join บน children ของ departments เพื่อดึงเฉพาะที่มี subdepartments (กล่าวคือ รากของต้นไม้ของเรา):

 

ใน index view เราตั้งค่า tree view แบบ nested โดยใช้สองระดับของ element <details> สำหรับ departments ของเรา:

 

ตอนนี้เรามี tree view ของ departments พร้อมชื่อผลิตภัณฑ์ที่ขำขันโดยเจตนาที่เราสำรวจได้โดยการเปิดและปิด:

จัดเก็บสถานะ UI ชั่วคราวใน Rails ได้อย่างง่ายดายด้วย Kredis

เราต้องการทำให้สถานะ disclosure ของหมวดหมู่แต่ละตัวคงอยู่ ซึ่งเราจะดูต่อไป

การทำให้สถานะ UI ของหมวดหมู่คงอยู่ใน Kredis

นี่คือสิ่งที่เราจะทำ ทีละขั้นตอน:

  1. เพิ่ม kredis_set ชื่อ open_department_ids ให้กับโมเดล User เหตุผลที่เราใช้ set ที่นี่คือมันไม่อนุญาต duplicates ดังนั้นเราจึงสามารถเพิ่มและลบ departments ของเราได้อย่างปลอดภัย

  2. สร้าง UIStateController ที่จะรับพารามิเตอร์ต่อไปนี้:

    • department_id
    • สถานะ open ของ department นั้น

    มันจะเพิ่มหรือลบ department นี้ไปยัง kredis_set สำหรับผู้ใช้ที่ล็อกอินอยู่ปัจจุบัน

  3. สร้าง Stimulus controller ซึ่งจะฟัง event toggle บน element details และส่ง payload ที่เกี่ยวข้อง

ลองเริ่มกันเถอะ!

การเพิ่มโครงสร้างข้อมูล Kredis ที่กล่าวมาให้กับโมเดล User ง่ายเพียงแค่เรียก kredis_set และส่ง identifier:

 

ต่อไป เราสร้าง UIStateController เพื่อรับการอัปเดตสถานะ UI โปรดทราบว่าเราต้องกำหนดค่า route ที่สร้างขึ้นให้เป็น endpoint patch:

 
 

การเจอกับ API ของ Kredis ครั้งแรกอยู่ใน controller เราเห็นว่ามันพยายามปฏิบัติตามความคาดหมายของนักพัฒนา Ruby มากที่สุด ดังนั้นคุณสามารถเพิ่มเข้า set ด้วย << และลบด้วย remove

 

สิ่งที่เกิดขึ้นคือเราสลับการมีอยู่ของ department_id เฉพาะใน set ตามพารามิเตอร์ open ที่ถูกส่งมาจาก client เพื่อให้สมบูรณ์ เราต้องเขียนโค้ดฝั่ง client เพื่อส่งการเปลี่ยนแปลงสถานะ UI นี้

เราจะใช้ @rails/request.js เพื่อดำเนินการ ดังนั้นเราต้อง pin มัน:

 

ใน Stimulus controller ใหม่ที่เราจะ attach ไปยัง element <details> เฉพาะ เรา append department ID และสถานะ open ของมันไปยังอ็อบเจกต์ FormData และ submit:

 

เราแก้ไขโค้ด view ตามที่เสนอ และฟัง event toggle ของแต่ละ element <details> เพื่อทริกเกอร์การอัปเดตสถานะ UI:

 

Rehydrate DOM ด้วยตนเอง

องค์ประกอบที่ขาดไปเพื่อให้ครบวงจรคือ rehydrating DOM ของเราให้อยู่ในสถานะที่ต้องการเมื่อผู้ใช้ refresh หน้า เราทำด้วยตนเองโดยเพิ่มแอตทริบิวต์ open ให้กับโหนด <details> (ถ้า department ID ของมันอยู่ใน Kredis set):

 

สุดท้าย นี่คือผลลัพธ์ สังเกตว่าสถานะเปิด/ปิดของโหนดต้นไม้แต่ละตัวถูกเก็บไว้ข้าม 2 ระดับ:

ต่อไป: Container ผู้ใช้ทั่วไปสำหรับสถานะ UI

ในส่วนแรกของชุด 2 ส่วนนี้ เราแนะนำ Kredis และสำรวจวิธีทำให้สถานะยุบ/ขยายของ UI คงอยู่และกู้คืนด้วย Kredis

เราใช้ตัวอย่างร้านค้าปลีกออนไลน์เพื่อเน้นว่า Kredis สามารถทำให้สถานะของโครงสร้างต้นไม้ที่ซับซ้อนคงอยู่ได้ ก่อนที่จะ rehydrate DOM ด้วยตนเองในที่สุด

อย่างไรก็ตาม นี่หมายความว่าเราต้องประดิษฐ์ Kredis keys มากมาย ครั้งหน้า เราจะเจาะลึกว่าสามารถแก้ปัญหานี้ได้อย่างไรด้วย container ผู้ใช้ทั่วไปสำหรับสถานะ UI

จนกว่าจะพบกันใหม่ ขอให้เขียนโค้ดสนุกสนาน!

P.S. หากคุณต้องการอ่านโพสต์ Ruby Magic ทันทีที่เผยแพร่ สมัครรับจดหมายข่าว Ruby Magic และจะไม่พลาดโพสต์ใดๆ!