موارد جدید در Rails 7.1

Rails 7 نسخه خوشایندی بود که ویژگی ها و تغییرات قابل توجهی را به همراه داشت. در باطن، Rails 7 بارگیری ناهمزمان پرس و جو و Zeitwerk را برای بارگذاری خودکار معرفی کرد. ظاهر Hotwire به راه حل پیش فرض برای برنامه های جدید Rails تبدیل شد.
Rails 7.1 به این ویژگی های قابل توجه اضافه می کند. در این پست، ما در مورد برخی از اضافات قابل توجه که احتمالا ارسال می شوند صحبت خواهیم کرد.
یک API جدید برای جستجوهای Async در Rails
با تکیه بر ویژگی قبلی Rails 7، Rails 7.1 اجرای برخی از پرس و جوها را به صورت ناهمزمان ممکن می کند. ریل 7 معرفی شد ActiveRecord::Relation#load_async
، که یک پرس و جو را در یک مخزن رشته پس زمینه زمان بندی می کند و به ما امکان می دهد کارهایی مانند این را انجام دهیم Post.where(published: true).load_async
.
در Rails 7.1، ما قادر خواهیم بود پرس و جوهای بیشتری را در رشته های پس زمینه اجرا کنیم. متدهای انبوه به صورت همزمان اجرا خواهند شد. با فرض اینکه دو یا چند پرس و جو مستقل را روی یک کار یا کنترلر اجرا می کنید، اگر برنامه شما بر اساس آن تنظیم شود، نتایج پرس و جو ممکن است سریعتر بازگردد.
برای اینکه این کار همانطور که در نظر گرفته شده عمل کند، دو گزینه پیکربندی وجود دارد که ارزش توجه به آنها را دارد:
config.active_record.async_query_executor
config.active_record.global_executor_concurrency
از جمله روش هایی که می توانید به صورت ناهمزمان در Rails 7.1 اجرا کنید عبارتند از async_sum
، async_pluck
، و async_count_by_sql
.
بازنشانی انجمن های مفرد
Rails 7.1 اجازه می دهد تا حافظه پنهان را در انجمن های منفرد تنظیم مجدد کنید. در حال حاضر، فقط می توانید کش را پاک کنید has_many
ارتباط با کلاسی مانند:
class Teacher < ActiveRecord::Base
has_many :students
has_one :classroom
end
teacher = Teacher.first
ما فقط می توانیم انجام دهیم teacher.students.reset
برای پاک کردن حافظه پنهان نتایج بازگردانده شده توسط teacher.students
. درخواستهای بعدی باید مجدداً به پایگاه داده برای مجموعه نتایج جدید در صورتی که برخی از دادهها کهنه میشوند، مراجعه کنند.
با Rails 7.1، ما آن را دریافت خواهیم کرد reset
روش بر روی الف has_one
اتحادیه. با استفاده از کلاس مثال بالا، Rails 7.1 به ما این امکان را می دهد teacher.classroom.reset_teacher
برای پاک کردن حافظه پنهان برای ارتباط بین teacher
و classroom
.
غیرفعال کردن روش های ایجاد شده توسط ActiveRecord#enum
ActiveRecord#enum
اگر یک Rails enum ایجاد کنید، دسته ای از روش ها را ایجاد می کند. Rails 7.1 گزینه ای برای انصراف از این روش های ایجاد شده ارائه می دهد. در اینجا یک مثال ساده آورده شده است:
class Payment < ActiveRecord::Base
enum :status, %i[succeeded failed], instance_methods: false
end
ریل ها روش های کمکی را ایجاد نمی کنند instance_methods: false
. در حال حاضر، ما انتظار داریم که روش هایی مانند:
payment = Payment.first
payment.succeeded?
payment.failed?
payment.succeeded!
payment.failed!
پشتیبانی از عبارات جدول مشترک
Rails 7.1 دارای پشتیبانی داخلی از Common Table Expressions (CTEs) خواهد بود. این تضمین میکند که کد مختصرتر است، اما مهمتر از آن، نیازی به استفاده از آن نیست Arel::Nodes
برای پرس و جوهای پیچیده
با Rails 7.1، ما یک نسخه جدید خواهیم داشت .with
روشی برای نوشتن پرس و جوهایی مشابه شکل زیر:
Post.with(
posts_with_comments: Post.where("comments_count > ?", 0),
posts_with_tags: Post.where("tags_count > ?", 0)
)
پشتیبانی از Async Bulk Record Destruction
همانطور که گفته شد، Rails 7.1 راه های مختلفی را برای اجرای کد به صورت ناهمزمان معرفی می کند. یکی از این موارد افزوده جدید به اجرای کدهای همگام، این است destroy_association_async_batch_size
پیکربندی
با این پیکربندی جدید، برنامه های Rails می توانند حداکثر تعداد رکوردهایی را تعیین کنند که در یک کار پس زمینه منفرد توسط dependent: :destroy_async
اتحادیه.
رفتار پیشفرض، که در آن تمام رکوردهای وابسته در یک کار پسزمینه زمانی که رکورد والد از بین میرود، از بین میرود، بدون تغییر باقی میماند. با این حال، اگر تعداد رکوردهای وابسته از پیکربندی جدید بیشتر شود، در چندین کار پس زمینه از بین خواهند رفت.
به روز رسانی های دیگر Rails 7.1
ActiveRecord::Relation#explain
گزینه ها را می پذیرد
Rails 7.1 به شما امکان می دهد تا از سیستم های پایگاه داده ای که پشتیبانی می کنند عبور دهید EXPLAIN
گزینه هایی به ActiveRecord::Relation#explain
. یک کوئری مثال ممکن است به این صورت باشد:
Customer.where(id: 1).joins(:orders).explain(:analyze, :verbose)
رکورد فعال regroup
Active Record امکان “گروه بندی مجدد” پرس و جوها را با یک جدید فراهم می کند regroup
روشی که می توان از این طریق استفاده کرد: Post.group(:title).regroup(:author)
. این معادل SQL تولید می کند SELECT posts.* FROM posts GROUP BY posts.author
.
همین امر را می توان در نسخه های فعلی Rails با کد دقیق تر به دست آورد:
Post.group(:title)..unscope(:group).group(:author)
جدید stub_const method
برای آزمایش
یک جدید stub_const
روش برای ActiveSupport::TestCase
اضافه خواهد شد که خرد برای مدت یک بازده ثابت است.
مثلا:
# World::List::Import::LARGE_IMPORT_THRESHOLD = 5000
stub_const(World::List::Import, :LARGE_IMPORT_THRESHOLD, 1) do
assert_equal 1, World::List::Import::LARGE_IMPORT_THRESHOLD
end
assert_equal 5000, World::List::Import::LARGE_IMPORT_THRESHOLD = 5000
با این حال، توجه داشته باشید که ثابت کردن یک ثابت بر مقدار آن در تمام رشتهها در یک راهاندازی چند رشتهای تأثیر میگذارد. این بدان معنی است که اگر چندین رشته همزمان به یک ثابت تکیه کنند، ممکن است تضاد همزمان و تضاد ایجاد شود.
چالش رمز عبور از طریق has_secure_password
Rails 7.1 عملکرد را بهبود بخشیده است has_secure_password
با افزودن a password_challenge
دسترسی و اعتبار سنجی مربوطه اعتبار سنجی تأیید می کند که الف password_challenge
با ذخیره شده مطابقت دارد password_digest
.
با این کار، پیادهسازی چالش رمز عبور به اندازه تأیید رمز عبور ساده میشود. این همچنین امکان استفاده مجدد از همان منطق رسیدگی به خطا را در نمایش و کنترلر فراهم می کند.
به عنوان مثال، به جای نوشتن کد جداگانه در کنترلر، به سادگی از منطق موجود برای تایید رمز عبور استفاده خواهید کرد.
password_params = params.require(:password).permit(
:password_challenge,
:password,
:password_confirmation,
).with_defaults(password_challenge: "")
if current_user.update(password_params)
# perform some work
end
ذخیره ضمیمه ها برگرداندن لکه
با Rails 7.1، وقتی پیوستها را در یک رکورد ذخیره میکنید، attach
روش حباب یا حباب های پیوست شده را برمی گرداند. این امکان استفاده مستقیم از روشهای blob را در پیوست میدهد. با این حال، اگر رکورد ذخیره نشود، attach
بر خواهد گشت false
.
در اینجا مثالی وجود دارد که کاربرد آن را نشان می دهد:
@user = User.create!(name: "Josh")
avatar = @user.avatar.attach(params[:avatar])
# You can now directly call blob methods as follows:
avatar.download
avatar.url
avatar.variant(:thumb)
ذخیره سازی توکن های CSRF در خارج از جلسات
Rails یک گزینه پیکربندی جدید را برای رسیدگی به ایجاد و اخراج بیش از حد میلیونها جلسه برای ذخیره یک توکن CSRF زمانی که جلسات در کوکیها ذخیره نمیشوند، معرفی کرده است.
این گزینه امکان استفاده از یک تابع لامبدا را برای ذخیره توکن CSRF در یک مکان سفارشی فراهم می کند، بنابراین ذخیره توکن های CSRF را در خارج از جلسات امکان پذیر می کند.
همچنین می توانید کلاس های استراتژی سفارشی برای ذخیره توکن های CSRF ایجاد کنید.
class CustomStore
def fetch(request)
# Return the token from a custom location
end
def store(request, csrf_token)
# Store the token in a custom location
end
def reset(request)
# Delete the stored session token
end
end
class ApplicationController < ActionController:x:Base
protect_from_forgery store: CustomStore.new
end
بررسی اعتبار برای شاخص های PostgreSQL
ایجاد نمایه ها مطابق شکل زیر ممکن است منجر به یک نمایه نامعتبر شود:
add_index :account, :active, algorithm: :concurrently
با Rails 7.1، می توانید اعتبار شاخص را همانطور که در اینجا نشان داده شده است تأیید کنید:
connection.index_exists?(:users, :email, valid: true)
connection.indexes(:users).select(&:valid?)
ActiveRecord::QueryMethods#select
هش را می پذیرد
ActiveRecord::QueryMethods#select
در Rails 7.1 اکنون هش از گزینه ها را می پذیرد. این به بهترین شکل با یک مثال نشان داده می شود:
# You can now write selects like this:
Post.joins(:comments).select(
posts: { id: :post_id, title: :post_title },
comments: { id: :comment_id, body: :comment_body}
)
# In place of this:
Post.joins(:comments).select(
"posts.id as post_id, posts.title as post_title,
comments.id as comment_id, comments.body as comment_body"
)
تعداد پردازنده ها با تعداد کارگران Puma مطابقت دارد
بهطور پیشفرض، برنامههای Rails که جدیداً تولید شدهاند، کارگران Puma دارند که تعداد کل پردازندههای فیزیکی روی دستگاه میزبان محدود میشود. این تنظیم پیش فرض را همیشه می توان در puma.rb
فایل.
را puma.rb
فایل برای برنامههای جدید Rails اکنون به شکل زیر خواهد بود:
if ENV["RAILS_ENV"] == "production"
worker_count = ENV.fetch("WEB_CONCURRENCY") { Concurrent.physical_processor_count }
workers worker_count if worker_count > 1
end
preload
و eager_load
انجمنهایی که باید نامحسوس باشند
Rails 7.1 این امکان را به شما اضافه می کند که ارتباط های از پیش بارگذاری شده و مشتاق بارگذاری شده را به روشی مشابه با Active Record حذف کنید. includes
، select
، و joins
روش ها کار می کنند
این ویژگی امکان استفاده از توابع انبوه را فراهم می کند has_many
انجمنهایی که قبلاً بارگیری شدهاند eager_load
یا preload
در پرس و جوهای موجود
یک مثال استفاده می تواند به این صورت باشد:
query.unscope(:eager_load, :preload).group(:id).select(:id)
Dockerfiles پیشفرض برای برنامههای New Rails
فایلهای Docker به عنوان یک گزینه پیشفرض برای برنامههای جدید Rails اضافه میشوند. فایل ها شامل:
Dockerfile
.dockerignore
bin/docker-entrypoint
این فایل ها به عنوان نقطه شروعی برای استقرار یک برنامه کاربردی در محیط تولید عمل می کنند و برای استفاده در طول توسعه در نظر گرفته نشده اند. با این حال، در صورت تمایل، می توانید با استفاده از این فایل ها را نادیده بگیرید --skip-docker
گزینه.
کنترل کننده سلامت پیش فرض
Rails 7.1 نقطه پایانی جدیدی را برای متعادل کننده های بار و مانیتورهای آپتایم معرفی می کند. نقطه پایان، نامگذاری شده است Rails::HealthController#show
، در برنامه های جدید Rails به مسیر “/up” نگاشت می شود. این اجازه می دهد تا متعادل کننده های بار و مانیتورهای آپتایم به راحتی در دسترس بودن برنامه را ردیابی کنند.
توجه داشته باشید که نظارت بر پایگاه داده، Redis و اتصالات شبکه داخلی به میکروسرویس هایی که یک برنامه به آنها متکی است باید به طور جداگانه مدیریت شود.
جدید Rails.env.local?
برای بررسی های محیطی
در Rails 7.1، یک نسخه جدید local?
روش را می توان برای ساده سازی بررسی های محیطی استفاده کرد.
شما می توانید کدهایی مانند زیر را جایگزین کنید:
if Rails.env.development? || Rails.env.test?
end
با:
if Rails.env.local?
end
جدید ActiveRecord::Persistence#update_attribute!
روش
Rails یک روش جدید اضافه کرده است، ActiveRecord::Persistence#update_attribute!
، که عملکرد مشابهی دارد update_attribute
اما استفاده می کند save!
بجای save
.
در اینجا نحوه استفاده از این روش جدید آورده شده است:
class Apm < ActiveRecord::Base
before_save :check_name
def check_name = throw(:abort) if name == "abort"
end
monitor = Apm.create(name: "App Signal")
# => #<Apm name: "App Signal">
monitor.update_attribute!(:name, "AppSignal")
# => #<Apm name: "AppSignal">
monitor.update_attribute!(:name, "abort")
# raises ActiveRecord::RecordNotSaved
الگوهایی که قادر به تعریف محلی های پذیرفته شده هستند
الگوها با گزینه ای از آرگومان های مورد نیاز که دارای مقادیر پیش فرض هستند، تقویت خواهند شد.
در حال حاضر، الگوها هر محلی را به عنوان آرگومان کلمه کلیدی می پذیرند. با 7.1، الگوهای Rails افراد محلی پذیرفته شده خاص را از طریق یک نظر جادویی تعریف می کنند.
این بهبود گزینه های کنترل و سفارشی سازی بیشتری را برای رفتار و عملکرد قالب فراهم می کند.
یک جزئی در Rails اکنون می تواند به شکل زیر باشد:
<%# locals: (title: "Default title", comment_count: 0) %>
<h2><%= title %></h2>
<span class="comment-count"><%= comment_count %></span>
بجای:
<% title = local_assigns[:title] || "Default title" %>
<% comment_count = local_assigns[:comment_count] || 0 %>
<h2><%= title %></h2>
<span class="comment-count"><%= comment_count %></span>
بسته بندی
همانطور که می بینید، Rails 7.1 نوید بهبودهای بیشتر در Rails 7 را می دهد.
برای اطلاعات بیشتر در مورد ویژگیها، بهروزرسانیها و رفع اشکال، یادداشتهای انتشار Rails 7.1 را بررسی کنید.
کد نویسی مبارک!
PS اگر میخواهید پستهای Ruby Magic را بهمحض انتشار مطبوعات بخوانید، در خبرنامه Ruby Magic مشترک شوید و هیچ پستی را از دست ندهید!