Computer >> Máy Tính >  >> Lập trình >> Ruby

Có gì mới trong Rails 7

Rails 7 ở ngay gần đó. Chúng tôi không có ngày phát hành được xác nhận, nhưng dự kiến ​​sẽ có trước Giáng sinh, vì vậy không lâu nữa sẽ đến. Phiên bản mới nhất khi bài đăng này được xuất bản là 7.0.0.rc1 , ứng cử viên phát hành đầu tiên.

Trong bài đăng này, chúng ta sẽ xem xét một số tính năng và thay đổi mới mà Rails 7 sẽ mang lại.

Không cần Node và Webpack

Bạn đã đọc đúng! JavaScript trong Rails 7 sẽ không yêu cầu NodeJS hoặc Webpack nữa. Và bạn vẫn có thể sử dụng các gói npm.

Việc vận chuyển ES6 với Babel và đóng gói với Webpack đòi hỏi rất nhiều thiết lập. Mặc dù Rails hỗ trợ nó khá tốt với Webpacker gem, điều này mang lại rất nhiều hành lý, rất khó để hiểu và thực hiện bất kỳ thay đổi nào, đặc biệt là trong khi duy trì khả năng nâng cấp.

Bây giờ, cài đặt mặc định cho các ứng dụng mới được tạo bằng rails new là sử dụng bản đồ nhập thông qua importmaps-rails gem.Thay vì viết package.json và cài đặt các phần phụ thuộc với npm hoặc yarn , bạn sử dụng ./bin/importmap CLI để ghim (hoặc bỏ ghim hoặc cập nhật) các phần phụ thuộc.

Ví dụ:để cài đặt date-fns :

$ ./bin/importmap pin date-fns

Thao tác này sẽ thêm một dòng trong config/importmap.rb như:

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

Trong mã JavaScript của mình, bạn có thể tiếp tục sử dụng mọi thứ như trước đây:

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

Một điều cần lưu ý với thiết lập này là không có sự chuyển đổi giữa những gì bạn viết và những gì trình duyệt nhận được. Đối với hầu hết các phần, điều này là ổn vì tất cả các trình duyệt quan trọng hiện đều hỗ trợ ES6.

Nhưng điều này cũng có nghĩa là bạn sẽ không thể sử dụng TypeScript hoặc JSX vì chúng yêu cầu chuyển đổi sang JS trước khi sử dụng.

Vì vậy, nếu bạn muốn sử dụng React với JSX, bạn vẫn phải quay lại một thiết lập khác (sử dụng webpack / rollup / esbuild).

Rails 7 có thể làm điều này cho bạn. Tất cả những gì bạn cần là một lệnh với chiến lược bạn đã chọn:

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

Turbolinks và UJS được Turbo và Stimulus thay thế

Các ứng dụng được tạo bằng Rails 7 sẽ nhận được Turbo và Stimulus (từ Hotwire) theo mặc định, thay vì Turbolinks và UJS. Hotwire là một cách tiếp cận mới cung cấp các bản cập nhật nhanh chóng cho DOM bằng cách gửi HTML qua dây.

Mã hóa ở Lớp cơ sở dữ liệu

Rails 7 cho phép đánh dấu các trường cơ sở dữ liệu nhất định là đã được mã hóa bằng cách sử dụng encrypts phương thức trên ActiveRecord::Base . Điều này có nghĩa là sau khi thiết lập ban đầu, bạn có thể viết mã như sau:

class Message < ApplicationRecord
  encrypts :text
end

Bạn có thể tiếp tục sử dụng các thuộc tính được mã hóa giống như bất kỳ thuộc tính nào khác. Rails 7 sẽ tự động mã hóa và giải mã nó giữa cơ sở dữ liệu và ứng dụng của bạn.

Nhưng điều này đi kèm với một điểm khó hiểu:bạn không thể truy vấn cơ sở dữ liệu theo trường đó trừ khi bạn chuyển deterministic: true tùy chọn encrypts Chế độ xác định kém an toàn hơn chế độ không xác định mặc định, vì vậy chỉ sử dụng nó cho các thuộc tính bạn thực sự cần truy vấn.

Truy vấn không đồng bộ

Hiện có một load_async mà bạn có thể sử dụng khi truy vấn dữ liệu để tìm nạp kết quả trong nền. Điều này đặc biệt quan trọng khi bạn cần tải một số truy vấn không liên quan từ một hành động của bộ điều khiển. Bạn có thể chạy:

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

Điều này sẽ kích hoạt cả hai truy vấn trong nền cùng một lúc. Vì vậy, nếu mỗi truy vấn mất 200 mili giây, thì tổng thời gian dành để tìm nạp dữ liệu là ~ 200 mili giây thay vì 400 mili giây, nếu chúng được tìm nạp nối tiếp.

Chế độ Zeitwerk cho Rails 7

Đây là một thay đổi đột phá đối với các ứng dụng cũ vẫn chạy trình tải cổ điển. Tất cả các ứng dụng Rails 7 đều phải sử dụng chế độ Zeitwerk, nhưng việc chuyển đổi khá dễ dàng. Xem toàn bộ hướng dẫn nâng cấp Zeitwerk.

Các bản cập nhật khác của Rails 7

Thử lại công việc không giới hạn thời gian

ActiveJob hiện cho phép chuyển :unlimited như attempts tham số trên retry_on . Rails sẽ tiếp tục thực hiện công việc mà không có bất kỳ số lần thử tối đa nào.

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

Các biến thể được đặt tên

Giờ đây, bạn có thể đặt tên cho các biến thể trên ActiveStorage thay vì chỉ định kích thước trên mỗi lần truy cập.

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) %>

Hash thành các thuộc tính HTML

Có một tag.attributes mới phương pháp để sử dụng trong các dạng xem dịch một hàm băm thành các thuộc tính HTML:

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

sẽ sản xuất

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

Ruby debug

Mặc định mới để gỡ lỗi đã thay đổi từ byebug vào debug đá quý.

Thay vì gọi byebug , bây giờ bạn cần gọi debugger trong mã để tham gia phiên gỡ lỗi.

Xác nhận một bản ghi duy nhất với sole

Khi truy vấn bản ghi, bây giờ bạn có thể gọi sole hoặc find_sole_by (thay vì first hoặc find_by ) khi bạn muốn khẳng định rằng truy vấn chỉ nên khớp với một bản ghi duy nhất.

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

Kiểm tra sự hiện diện / Sự vắng mặt của một Hiệp hội

Bây giờ chúng ta có thể sử dụng where.associated(:association) để kiểm tra xem một liên kết có xuất hiện trên bản ghi hay không thay vì tham gia và kiểm tra sự tồn tại của một id.

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

Truyền trực tuyến các tệp được tạo từ các tác vụ của bộ điều khiển

Bây giờ bạn có thể sử dụng send_stream bên trong hành động của bộ điều khiển để bắt đầu phát trực tuyến tệp đang được tạo nhanh chóng.

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

Điều này cung cấp phản hồi ngay lập tức (một phần) cho người dùng để họ biết điều gì đó đang xảy ra và có thêm lợi ích nếu bạn triển khai trên Heroku.

Vì tệp sẽ bắt đầu phát trực tuyến ngay lập tức, Heroku sẽ không ngắt kết nối, điều này có nghĩa là bạn không cần phải sử dụng đến các công việc nền để tạo tệp một lần mất hơn 30 giây.

Nâng cấp lên Rails 7

Cũng như các phiên bản trước của Rails, việc nâng cấp rất đơn giản. Mặc dù chúng tôi chưa có hướng dẫn nâng cấp chính thức nhưng các bước sẽ vẫn như cũ:

  1. Thay đổi số phiên bản Rails trong Gemfile (7.0.0.rc1 kể từ ngày xuất bản) và chạy bundle update .
  2. Chạy ứng dụng rails bundle exec rails app:update . Thực hiện theo CLI tương tác và thêm / thay thế / sửa đổi các tệp theo yêu cầu.
  3. Chạy thử nghiệm của bạn và xác minh mọi thứ hoạt động như mong đợi.

Kết thúc

Bạn có thể xem danh sách đầy đủ các bản sửa lỗi, tính năng và thay đổi trong ghi chú phát hành của Rails 7.

Nếu bạn vẫn đang chạy Rails 6 trở xuống, xin lưu ý rằng với bản phát hành cuối cùng của Rails 7, Rails 6.1 sẽ chuyển sang chế độ "chỉ các vấn đề bảo mật" và sẽ không nhận được các bản sửa lỗi nữa. Điều này cũng sẽ đánh dấu EOL cho Rails 5.2, vì nó sẽ không nhận được bất kỳ bản sửa lỗi nào nữa.

Chúc bạn viết mã vui vẻ!

Tái bút. Nếu bạn muốn đọc các bài đăng của Ruby Magic ngay khi chúng xuất hiện trên báo chí, hãy đăng ký bản tin Ruby Magic của chúng tôi và không bao giờ bỏ lỡ một bài đăng nào!