برنامه نویسی

موارد جدید در 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 مشترک شوید و هیچ پستی را از دست ندهید!

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا