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

มีอะไรใหม่ใน Rails 7

Rails 7 อยู่ใกล้แค่เอื้อม เราไม่มีวันวางจำหน่ายที่ยืนยันได้ แต่คาดว่าจะวางจำหน่ายก่อนวันคริสต์มาส ดังนั้นอีกไม่นานเกินรอ เวอร์ชันล่าสุดที่เผยแพร่ในโพสต์นี้คือ 7.0.0.rc1 ซึ่งเป็นผู้สมัครรุ่นแรกที่เปิดตัว Basecamp, HEY, Github และ Shopify ต่างก็ใช้ Rails 7 alpha ในการผลิต ดังนั้นเราจึงคาดหวังได้ว่าตัวเลือกที่วางจำหน่ายจะค่อนข้างเสถียร

ในโพสต์นี้ เราจะมาดูฟีเจอร์และการเปลี่ยนแปลงใหม่ๆ ที่ Rails 7 จะนำเสนอ

ไม่จำเป็นต้องใช้โหนดและ Webpack

ใช่คุณอ่านถูกต้องแล้ว! JavaScript ใน Rails 7 จะไม่ต้องใช้ NodeJS หรือ Webpack อีกต่อไป และคุณยังสามารถใช้แพ็คเกจ npm ได้

การแปลง ES6 ด้วย Babel และการรวมกับ Webpack จำเป็นต้องมีการตั้งค่าจำนวนมาก ในขณะที่ Rails รองรับได้ค่อนข้างดีด้วย Webpacker อัญมณีนี้นำสัมภาระจำนวนมาก ยากที่จะเข้าใจและทำการเปลี่ยนแปลงใด ๆ โดยเฉพาะอย่างยิ่งในขณะที่ยังคงอัพเกรดได้

ตอนนี้ ค่าเริ่มต้นสำหรับแอปใหม่ที่สร้างด้วย rails new คือการใช้แผนที่นำเข้าผ่าน importmaps-rails gem.แทนที่จะเขียน package.json และติดตั้งการพึ่งพาด้วย npm หรือ yarn คุณใช้ ./bin/importmap CLI เพื่อตรึง (หรือเลิกตรึงหรืออัปเดต) การพึ่งพา

ตัวอย่างเช่น ในการติดตั้ง date-fns :

$ ./bin/importmap pin date-fns

สิ่งนี้จะเพิ่มบรรทัดใน config/importmap.rb ชอบ:

pin "date-fns", to: "https://ga.jspm.io/npm:date-fns@2.27.0/esm/index.js"

ในโค้ด JavaScript คุณสามารถใช้ทุกอย่างต่อไปได้เหมือนเดิม:

import { formatDistance, subDays } from "date-fns";
 
formatDistance(subDays(new Date(), 3), new Date(), { addSuffix: true });
//=> "3 days ago"

สิ่งหนึ่งที่ต้องคำนึงถึงในการตั้งค่านี้คือไม่มีการข้ามระหว่างสิ่งที่คุณเขียนกับสิ่งที่เบราว์เซอร์ได้รับ โดยส่วนใหญ่แล้ว ถือว่าใช้ได้เนื่องจากเบราว์เซอร์ที่มีความสำคัญในขณะนี้รองรับ ES6 ได้ทันที

แต่ยังหมายความว่าคุณจะไม่สามารถใช้ TypeScript หรือ JSX ได้ เนื่องจากต้องใช้การ transpilation ไปยัง JS ก่อนใช้งาน

ดังนั้น หากคุณต้องการใช้ React กับ JSX คุณยังต้องถอยกลับไปใช้การตั้งค่าอื่น (โดยใช้ webpack/rollup/esbuild)

Rails 7 ช่วยคุณได้ สิ่งที่คุณต้องมีคือคำสั่งเดียวด้วยกลยุทธ์ที่คุณเลือก:

$ ./bin/rails javascript:install:[esbuild|rollup|webpack]

Turbolinks และ UJS ถูกแทนที่ด้วย Turbo และ Stimulus

แอปพลิเคชันที่สร้างด้วย Rails 7 จะได้รับ Turbo และ Stimulus (จาก Hotwire) ตามค่าเริ่มต้น แทนที่จะเป็น Turbolinks และ UJS Hotwire เป็นแนวทางใหม่ที่มอบการอัปเดต DOM อย่างรวดเร็วด้วยการส่ง HTML ผ่านสาย

การเข้ารหัสที่ชั้นฐานข้อมูล

Rails 7 อนุญาตให้ทำเครื่องหมายฟิลด์ฐานข้อมูลบางฟิลด์ว่าเข้ารหัสโดยใช้ encrypts วิธีการใน ActiveRecord::Base . ซึ่งหมายความว่าหลังจากการตั้งค่าเริ่มต้น คุณสามารถเขียนโค้ดดังนี้:

class Message < ApplicationRecord
  encrypts :text
end

คุณสามารถใช้แอตทริบิวต์ที่เข้ารหัสต่อไปได้เช่นเดียวกับแอตทริบิวต์อื่นๆ Rails 7 จะเข้ารหัสและถอดรหัสโดยอัตโนมัติระหว่างฐานข้อมูลและแอปพลิเคชันของคุณ

แต่สิ่งนี้มาพร้อมกับความแปลกเล็กน้อย:คุณไม่สามารถสืบค้นฐานข้อมูลโดยฟิลด์นั้นเว้นแต่คุณจะผ่าน deterministic: true ตัวเลือก encrypts เมธอด โหมดดีเทอร์มินิสติกมีความปลอดภัยน้อยกว่าโหมดดีเทอร์มินิสติกที่เป็นค่าเริ่มต้น ดังนั้นให้ใช้เฉพาะกับแอตทริบิวต์ที่คุณต้องการค้นหาจริงๆ เท่านั้น

การสืบค้นแบบอะซิงโครนัส

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

def PostsController
  def index
    @posts = Post.load_async
    @categories = Category.load_async
  end
end

การดำเนินการนี้จะเริ่มทำงานทั้งสองคำค้นหาในพื้นหลังพร้อมกัน ดังนั้น หากการสืบค้นแต่ละครั้งใช้เวลา 200 มิลลิวินาที เวลาทั้งหมดที่ใช้ในการดึงข้อมูลจะอยู่ที่ ~200 มิลลิวินาที แทนที่จะเป็น 400 มิลลิวินาที หากมีการดึงข้อมูลแบบอนุกรม

โหมด Zeitwerk สำหรับ Rails 7

นี่เป็นการเปลี่ยนแปลงครั้งใหญ่สำหรับแอปพลิเคชันรุ่นเก่าที่ยังคงเรียกใช้ตัวโหลดแบบคลาสสิก แอปพลิเคชั่น Rails 7 ทั้งหมดต้องใช้โหมด Zeitwerk แต่สวิตช์นั้นค่อนข้างง่าย ดูคู่มือการอัปเกรด Zeitwerk ฉบับเต็ม

อัพเดต Rails 7 อื่นๆ

ลองใหม่ได้ไม่จำกัดครั้ง

ActiveJob อนุญาตให้ส่ง :unlimited เป็น attempts พารามิเตอร์บน retry_on . Rails จะพยายามทำงานต่อไปโดยไม่มีจำนวนครั้งสูงสุด

class MyJob < ActiveJob::Base
  retry_on(AlwaysRetryException, attempts: :unlimited)
 
  def perform
    raise "KABOOM"
  end
end

ชื่อตัวแปร

คุณตั้งชื่อตัวแปรได้แล้วใน ActiveStorage แทนที่จะระบุขนาดในทุกการเข้าถึง

class User < ApplicationRecord
  has_one_attached :avatar do |attachable|
    attachable.variant :thumb, resize: "100x100"
  end
end
 
#Call avatar.variant(:thumb) to get a thumb variant of an avatar:
<%= image_tag user.avatar.variant(:thumb) %>

แฮชเป็นแอตทริบิวต์ HTML

มี tag.attributes ใหม่ วิธีการใช้ในมุมมองที่แปลแฮชเป็นแอตทริบิวต์ HTML:

<input <%= tag.attributes(type: :text, aria: { label: "Search" }) %>>

จะผลิต

<input type="text" aria-label="Search" />

ทับทิม debug

ค่าเริ่มต้นใหม่สำหรับการดีบักได้เปลี่ยนจาก byebug ไปที่ debug พลอย

แทนที่จะเรียก byebug ตอนนี้คุณต้องเรียก debugger ในรหัสเพื่อเข้าสู่เซสชันการดีบัก

ยืนยันระเบียนเดียวด้วย sole

เมื่อทำการสอบถามระเบียน ตอนนี้คุณสามารถเรียก sole หรือ find_sole_by (แทน first หรือ find_by ) เมื่อคุณต้องการยืนยันว่าการสืบค้นควรตรงกับระเบียนเดียวเท่านั้น

Product.where(["price = %?", price]).sole
# => ActiveRecord::RecordNotFound      (if no Product with given price)
# => #<Product ...>                    (if one Product with given price)
# => ActiveRecord::SoleRecordExceeded  (if more than one Product with given price)
 
user.api_keys.find_sole_by(key: key)
# as above

ตรวจสอบสถานะ/การไม่มีสมาคม

ขณะนี้สามารถใช้ where.associated(:association) เพื่อตรวจสอบว่ามีการเชื่อมโยงอยู่ในบันทึกแทนที่จะเข้าร่วมและตรวจสอบการมีอยู่ของรหัส

# Before:
account.users.joins(:contact).where.not(contact_id: nil)
 
# After:
account.users.where.associated(:contact)

สตรีมไฟล์ที่สร้างจากการทำงานของคอนโทรลเลอร์

ตอนนี้คุณสามารถใช้ send_stream ภายในแอ็คชันคอนโทรลเลอร์เพื่อเริ่มสตรีมไฟล์ที่สร้างขึ้นทันที

send_stream(filename: "subscribers.csv") do |stream|
  stream.write "email_address,updated_at\n"
 
  @subscribers.find_each do |subscriber|
    stream.write "#{subscriber.email_address},#{subscriber.updated_at}\n"
  end
end

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

เนื่องจากไฟล์จะเริ่มสตรีมทันที Heroku จะไม่ยุติการเชื่อมต่อ ซึ่งหมายความว่าคุณไม่จำเป็นต้องหันไปใช้งานพื้นหลังเพื่อสร้างไฟล์แบบใช้ครั้งเดียวที่ใช้เวลานานกว่า 30 วินาที

กำลังอัปเกรดเป็น Rails 7

เช่นเดียวกับ Rails เวอร์ชันก่อนหน้า การอัปเกรดทำได้ง่าย แม้ว่าเราจะยังไม่มีคู่มือการอัปเกรดอย่างเป็นทางการ แต่ขั้นตอนจะยังคงเหมือนเดิม:

  1. เปลี่ยนหมายเลขเวอร์ชัน Rails ใน Gemfile (7.0.0.rc1 ณ วันที่เผยแพร่) และเรียกใช้ bundle update .
  2. เรียกใช้ bundle exec rails app:update . ทำตาม CLI แบบโต้ตอบและเพิ่ม/แทนที่/แก้ไขไฟล์ตามต้องการ
  3. ทำการทดสอบและยืนยันว่าทุกอย่างทำงานได้ตามที่คาดไว้

สรุป

คุณสามารถดูรายการการแก้ไขข้อบกพร่อง คุณลักษณะ และการเปลี่ยนแปลงทั้งหมดได้ในบันทึกประจำรุ่น Rails 7 ซึ่งยังไม่ครอบคลุมในขณะนี้ แต่คาดว่าจะได้รับการอัปเดตเร็วๆ นี้

หากคุณยังคงใช้งาน Rails 6 หรือต่ำกว่า โปรดทราบว่าใน Rails 7 รุ่นสุดท้าย Rails 6.1 จะเข้าสู่โหมด "เฉพาะปัญหาด้านความปลอดภัย" และจะไม่ได้รับการแก้ไขข้อผิดพลาดอีกต่อไป การดำเนินการนี้จะทำเครื่องหมาย EOL สำหรับ Rails 5.2 ด้วย เพราะจะไม่ได้รับการแก้ไขใดๆ อีกต่อไป

ขอให้สนุกกับการเขียนโค้ด!

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