พบกับ Volt, Ruby Framework ที่สดใสสำหรับการใช้งานแบบไดนามิก

เผยแพร่แล้ว: 2022-03-11

Volt เป็นเฟรมเวิร์ก Ruby ที่ออกแบบมาสำหรับแอปพลิเคชันที่มีข้อมูลจำนวนมาก ทั้งฝั่งเซิร์ฟเวอร์และฝั่งไคลเอ็นต์เขียนด้วย Ruby (ซึ่งจากนั้นคอมไพล์เป็น JS โดยใช้ OPAL) ซึ่งช่วยให้นักพัฒนาสามารถเขียนแอปพลิเคชันแบบไดนามิกได้โดยไม่ต้องเขียนโค้ด Javascript แม้แต่บรรทัดเดียว หากคุณเป็นแฟน Ruby อย่างฉัน คุณจะต้องชอบ Framework นี้

ในความพยายามที่จะทำให้เว็บแอปพลิเคชันมีไดนามิกมากขึ้น กรอบงาน Javascript ส่วนหน้าเช่น Angular.js, Backbone.js และ Ember.js ได้รับความนิยมอย่างมาก อย่างไรก็ตาม เฟรมเวิร์กเหล่านี้มักต้องการแอปพลิเคชันแบ็คเอนด์จึงจะมีประโยชน์ ดังนั้นจึงใช้ร่วมกับเฟรมเวิร์กของเว็บ เช่น Ruby on Rails และ Django

ในทางกลับกัน Ruby framework Volt สามารถจัดการส่วนหลังและส่วนหน้าแบบไดนามิก เนื่องจากฟังก์ชันทั้งสองได้รับการผสานรวมอย่างแน่นหนาในแกนกลาง (อันที่จริง Volt เป็นเหมือนสถาปัตยกรรม MVVM มากกว่า ซึ่งใช้ประโยชน์จากข้อดีของการผูกข้อมูล) จึงทำให้นักพัฒนาสามารถสร้างแอปพลิเคชันเหล่านี้ได้อย่างรวดเร็ว

คุณลักษณะที่ยอดเยี่ยมมากที่ออกมาจากกล่องคือคุณลักษณะเรียลไทม์ของโวลต์ หากคุณเคยสร้างแอปพลิเคชันตามเวลาจริง คุณจะรู้ว่ากระบวนการนี้อาจเป็นเรื่องที่ท้าทาย คุณอาจใช้ AJAX-polling, เว็บซ็อกเก็ต, Server-Sent Events (SSE) หรือแม้แต่ใช้บริการภายนอก เพิ่มความซับซ้อนให้กับแอปพลิเคชัน และอาจมีค่าใช้จ่ายเพิ่มเติม . ต่างจากเฟรมเวิร์กอื่นๆ Volt รักษาการเชื่อมต่อกับเซิร์ฟเวอร์ให้คงอยู่ (ผ่านซ็อกเก็ตเว็บ) ดังนั้นแทนที่จะส่งคำขอ Ajax สำหรับแต่ละการกระทำ มันส่งการเปลี่ยนแปลงไปยังไคลเอนต์ทั้งหมดทันที ไม่จำเป็นต้องมีการกำหนดค่าเพื่อให้ใช้งานได้

พบกับ Volt, Ruby Framework ที่สดใสสำหรับการใช้งานแบบไดนามิก

การใช้โวลต์เพื่อสร้างแอปพลิเคชั่นแชท

ในบทช่วยสอนเกี่ยวกับกรอบงาน Ruby นี้ ฉันจะนำคุณผ่านขั้นตอนการสร้างแอปพลิเคชันแบบเรียลไทม์โดยใช้ Volt และจะมีวิธีใดที่จะดีไปกว่าแอปพลิเคชันแชทในการแสดงความสามารถของมัน เนื่องจากการแชทยังคงเป็นกรณีการใช้งานอันดับหนึ่งของแอปพลิเคชันแบบเรียลไทม์

ก่อนอื่น เรามาติดตั้ง Volt และ MongoDB กันก่อน กระบวนการหลังนี้จะไม่ครอบคลุมในรายละเอียด:

 gem install volt brew install mongodb
 mkdir -p /data/db

(สร้าง dbpath)

 chown `id -u` /data/db (change the owner to have the proper dbpath permissions)

ตอนนี้เราพร้อมที่จะสร้างแอปแรกของเราแล้ว ให้เรียกว่า 'แชท' เราสามารถทำได้ง่ายๆ ในสองสามบรรทัด:

 volt new chat cd chat

โครงสร้างเอกสารมีความคล้ายคลึงกับ Rails ความแตกต่างหลัก ๆ ที่ผู้ใช้ Rails จะสังเกตเห็นก็คือ เรามีโฟลเดอร์พิเศษภายในแอพที่มีโฟลเดอร์ที่เหลือ เช่น สินทรัพย์ ตัวควบคุม โมเดล และมุมมอง โฟลเดอร์พิเศษนี้คือ 'ส่วนประกอบ'

ส่วนประกอบเป็นส่วนแยกของแอป หน้าทั้งหมดภายในคอมโพเนนต์จะแสดงผลโดยไม่ต้องโหลดหน้าซ้ำ เนื่องจากไฟล์ทั้งหมดสำหรับองค์ประกอบนั้นถูกโหลดด้วยคำขอ http เริ่มต้น ดังนั้นหากเราไปที่หน้าขององค์ประกอบอื่น คำขอ http ใหม่จะถูกสร้างขึ้นและหน้าจะถูก 'โหลดใหม่' '. สำหรับตัวอย่างนี้ ให้ใช้คอมโพเนนต์เริ่มต้นที่เรียกว่า 'main'

มาเริ่มเซิร์ฟเวอร์กันโดยเรียกใช้คำสั่ง 'volt server' ในคอนโซล และดูว่ามันมีลักษณะอย่างไรในเบราว์เซอร์โดยไปที่ localhost:3000:

 volt server

อย่าลืมเริ่ม MongoDB ในคอนโซลด้วย:

 mongod

เราสังเกตได้ว่า Volt มาพร้อมกับหน้าเริ่มต้นจำนวนหนึ่ง รวมทั้ง 'Home' และ 'About' สิ่งเหล่านี้สามารถปรับแต่งได้ทันที

อีกอย่างที่ควรกล่าวถึงคือปุ่มเข้าสู่ระบบที่ด้านขวาบนของหน้า Volt มีฟังก์ชัน "ผู้ใช้" ที่รวมเข้ากับเฟรมเวิร์กผ่านอัญมณี 'volt-user-templates' ซึ่งให้วิธีการลงทะเบียนและรับรองความถูกต้องของผู้ใช้ทันทีที่แกะออกจากกล่อง

เริ่มต้น

ตอนนี้ มาเริ่มทำงานกับแอพของเรากันเถอะ ก่อนอื่นเราไม่ต้องการหน้า 'เกี่ยวกับ' เพื่อดำเนินการต่อและลบสิ่งต่อไปนี้: ไฟล์ app/main/views/main/about.html การดำเนินการเกี่ยวกับใน app/main/controllers/main_controller.rb ให้ลบเส้นทาง /about ใน app/main/config/routes.rb และลิงก์ nav ใน app/main/views/main/main.html

 <ul class="nav nav-pills pull-right"> <:nav href="/" text="Home" /> <:user-templates:menu /> </ul>

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

 <:Body> <h1>Home</h1> <div class="row"> <div class="col-md-4"> {{ _users.each do |user| }} <div class="contact"> {{user._name}} </div> {{ end }} </div> </div>

ขณะนี้ผู้ใช้ที่ลงทะเบียนทั้งหมดกำลังแสดงอยู่ในหน้าแรก โปรดทราบว่ารหัสที่เขียนภายใน {{ }} เป็นรหัส Ruby ที่ดำเนินการ วิธีนี้ทำให้เราสามารถทำซ้ำในคอลเล็กชันของผู้ใช้และพิมพ์แต่ละรายการได้

ตามที่คุณอาจสังเกตเห็น 'ผู้ใช้' คือชื่อของคอลเล็กชันที่จัดเก็บผู้ใช้ทั้งหมด สิ่งที่ควรคำนึงถึงคือคุณลักษณะสามารถเข้าถึงได้ด้วยเครื่องหมายขีดล่าง '' ที่ต่อท้ายชื่อแอตทริบิวต์ เพื่อให้ใช้งานได้ เราต้องเพิ่มโค้ดหนึ่งบรรทัดที่ด้านบนของไฟล์ main_controller.rb :

 model :store

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

ตอนนี้ไม่มีอะไรน่าตื่นเต้นในหน้านี้ เราแค่แสดงรายชื่อผู้ใช้ที่ลงทะเบียน ตอนนี้ฉันขอสามารถเลือกผู้ใช้ที่จะส่งข้อความถึง ลบชื่อผู้ใช้ที่ล็อกอินอยู่ออกจากรายการ (เนื่องจากเขาไม่สามารถส่งข้อความถึงตัวเองได้) แสดงรายการเฉพาะการตรวจสอบสิทธิ์ ผู้ใช้และแสดงหน้า 'แลนดิ้ง' แก่ผู้ใช้ที่ไม่ผ่านการตรวจสอบสิทธิ์:

 <:Body> <h1>Home</h1> {{ if Volt.user }} <div class="row"> <div class="col-md-4"> {{ _users.each do |user| }} {{ if user._id != Volt.user._id }} <div class="contact {{ if params._user_id == user._id }} active {{ end }}" e-click="select_conversation(user)"> {{user._name}} </div> {{ end }} {{ end }} </div> </div> {{ else }} <p>This is a sample application built with Volt to demonstrate its real-time capabilities. Please log in to access it.</p> {{ end }}

Volt.user ส่งคืนผู้ใช้ปัจจุบัน (เข้าสู่ระบบ) หรือศูนย์

แอตทริบิวต์ e-click ช่วยให้เราเลือกวิธีการจากตัวควบคุมที่จะถูกเรียกเมื่อองค์ประกอบนั้นถูกคลิก

คุณสมบัติและ CSS

อันที่จริง แอตทริบิวต์ 'e-' ทั้งหมดเป็นตัวประสานเหตุการณ์ในหน่วยโวลต์ ตัวอย่างเช่น เราสามารถเพิ่ม e-submit ลงในแบบฟอร์มเพื่อเลือกการดำเนินการที่จะเรียกใช้บนคอนโทรลเลอร์ได้ เราจะเพิ่ม ID ผู้ใช้ที่ 'เลือกแล้ว' ให้กับพารามิเตอร์ เพื่อให้เราสามารถทราบได้ว่าอันไหนถูกเลือกแล้ว และเพิ่มคลาสที่เรียกว่า 'ใช้งานอยู่' ซึ่งเราสามารถจัดรูปแบบได้ในภายหลัง

ตอนนี้ มาสร้างเมธอด select_conversation ในคอนโทรลเลอร์กัน:

 def select_conversation(user) params._user_id = user._id end

และนั่นคือทั้งหมด – หากคุณตรวจสอบหน้าอีกครั้ง คุณจะเห็นว่า URL เปลี่ยนแปลงทุกครั้งที่คุณคลิกที่ชื่อผู้ใช้ นอกจากนี้ คลาส 'ใช้งานอยู่' กำลังถูกเพิ่มเข้าไปในองค์ประกอบนั้น ดังนั้นเรามาเพิ่ม CSS เพื่อให้มองเห็นได้ (ฉันจะไปข้างหน้าและเพิ่ม CSS สำหรับรายการที่เราจะเพิ่มในภายหลัง):

 .conversation{ form{ input{ margin: 10px 0 5px 0; } } }
 .contact{ width:100%; padding:5px; margin: 4px 0; font-size:15px; cursor:pointer; &:hover{ background-color: #FAFAFA; } &.active{ background-color: #337ab7; color: #FFF; } .badge{ background-color: #900; } }
 .message{ max-width: 80%; padding:10px 15px; margin: 5px 0; background-color: #FEFEFE; border: 1px solid #E7E7E7; border-radius: 5px; float: left; clear:both; &.sent{ background-color: #E4F3DB; border: 1px solid #B7D0A7; float: right; } p{ margin:0; } }

ตอนนี้ มาสร้างแบบฟอร์มทางด้านขวาเพื่อส่งข้อความถึงผู้ใช้แต่ละคน:

 <:Body> <h1>Home</h1> {{ if Volt.user }} <div class="row"> <div class="col-md-4"> {{ _users.each do |user| }} {{ if user._id != Volt.user._id }} <div class="contact {{ if params._user_id == user._id }} active {{ end }}" e-click="select_conversation(user)"> {{user._name}} </div> {{ end }} {{ end }} </div> {{ if params._user_id }} <div class="col-md-8 well conversation"> {{ current_conversation.each do |message| }} <div class="message {{ if message._sender_id == Volt.user._id }} sent {{ end }}"> <p>{{ message._text }}</p> </div> {{ end }} {{ if current_conversation.count == 0 }} <p>You have no messages yet. Start chatting!</p> {{ else }} <div class="clearfix"></div> {{ end }} <form e-submit="send_message" role="form"> <div class="form-group"> <input class="form-control" type="text" placeholder="Write a message" value="{{ page._new_message }}" /> <button type="submit" class="btn btn-primary pull-right">Submit</button> </div> </form> </div> {{ end }} </div> {{ else }} <p>This is a sample application built with Volt to demonstrate its real-time capabilities. Please log in to access it.</p> {{ end }}

อันดับแรก เรากำลังตรวจสอบว่ามีผู้ใช้ที่เลือกไว้ก่อนที่จะแสดงแบบฟอร์ม จากนั้นเราแสดงข้อความทั้งหมดจากการสนทนาปัจจุบัน (การสนทนากับผู้ใช้ที่เลือก) จากวิธีการในตัวควบคุมที่เราจะกำหนดไว้เล็กน้อย และที่ด้านล่าง เรากำลังแสดงแบบฟอร์มสำหรับการส่งข้อความใหม่

โปรดสังเกตว่าค่าของอินพุตเป็นแอตทริบิวต์ที่เรากำลังสร้างบนโมเดลการรวบรวมเพจ เนื่องจากเราไม่ต้องการให้จัดเก็บไว้ในที่เก็บข้อมูล ตอนนี้ มากำหนดวิธีการ current_conversation และ send_message ในคอนโทรลเลอร์:

 def send_message unless page._new_message.strip.empty? _messages << { sender_id: Volt.user._id, receiver_id: params._user_id, text: page._new_message } page._new_message = '' end end def current_conversation _messages.find({ "$or" => [{ sender_id: Volt.user._id, receiver_id: params._user_id }, { sender_id: params._user_id, receiver_id: Volt.user._id }] }) end

ในเมธอด send_message เราเพิ่มข้อความใหม่ไปยังคอลเล็กชันหากข้อความไม่ว่างเปล่า (เรากำลังตรวจสอบอินไลน์เพื่อไม่ให้ยุ่งกับการตรวจสอบความถูกต้องในขณะนี้) จากนั้นเราตั้งค่าหน้า ._new_message to '' ดังนั้น เราล้างช่องป้อนข้อมูล

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

ปิดท้ายด้วยการแจ้งเตือนแบบเรียลไทม์

สุดท้ายนี้ ฉันต้องการระบบการแจ้งเตือนบางอย่าง เพื่อให้ผู้ใช้มองเห็นได้เมื่อมีผู้ใช้รายอื่นส่งข้อความถึงพวกเขา

มาเพิ่มคอลเลกชั่นใหม่ชื่อ _notifications กันเถอะ และสร้างคอลเลกชั่นใหม่หลังจากแต่ละข้อความถูกส่งไป:

 def send_message unless page._new_message.strip.empty? _messages << { sender_id: Volt.user._id, receiver_id: params._user_id, text: page._new_message } _notifications << { sender_id: Volt.user._id, receiver_id: params._user_id } page._new_message = '' end end def select_conversation(user) params._user_id = user._id unread_notifications_from(user).then do |results| results.each do |notification| _notifications.delete(notification) end end page._new_message = '' end def unread_notifications_from(user) _notifications.find({ sender_id: user._id, receiver_id: Volt.user._id }) end

นอกจากนี้ เราจำเป็นต้องลบการแจ้งเตือนหลังจากผู้ใช้เลือกการสนทนาและเห็นข้อความใหม่ ดังนั้นฉันจึงเพิ่มส่วนนั้นในเมธอด select_conversation

มาเพิ่มตัวนับการแจ้งเตือนถัดจากชื่อผู้ใช้:

 <div class="contact {{ if params._user_id == user._id }} active {{ end }}" e-click="select_conversation(user)"> {{user._name}} {{ if unread_notifications_from(user).count > 0 }} <span class="badge"> {{ unread_notifications_from(user).count }} </span> {{ end }} </div>

ตอนนี้แอพพร้อมแล้ว คุณสามารถเปิดเบราว์เซอร์สองสามตัวและเริ่มทดสอบความสามารถแบบเรียลไทม์ของ Volt

โวลต์คุ้มค่าที่จะลอง

แม้ว่าเฟรมเวิร์กของ Volt จะยังไม่โตเต็มที่และแข็งแกร่งเท่ากับเฟรมเวิร์ก Ruby ยอดนิยมส่วนใหญ่ที่มีมานานหลายปี (ในขณะที่ Volt ยังอยู่ในช่วงเบต้า) แต่ก็คุ้มค่าที่จะพิจารณาและศึกษา

ในกรณีที่คุณสนใจ ใช้บทแนะนำกรอบงาน Ruby นี้เพื่อนำโวลต์ออกไป จับตาดูการพัฒนาเพิ่มเติม เนื่องจาก Volt ดูเหมือนเฟรมเวิร์ก Ruby ที่มีแนวโน้มมาก แม้ในช่วงเริ่มต้นของการพัฒนา

มีฟีเจอร์ใหม่เจ๋งๆ มากมายในท่อ และฉันค่อนข้างแน่ใจว่าโวลต์จะมีความเกี่ยวข้องมากขึ้นในอีกไม่กี่ปีข้างหน้า เนื่องจากมีผู้คนเริ่มทดลองกับมันมากขึ้น เนื่องจากฟีเจอร์ที่เป็นนวัตกรรมมากมาย นักพัฒนาหลายคนอาจตกหลุมรัก Volt และใช้สำหรับโปรเจ็กต์ Ruby ถัดไป