Duyuru

  • Rafael Mendonça França, 8.1.3’ün ardından 8.1.4’ün çıktığını duyuruyor. Değişiklikleri saymıyor: GitHub’daki sürüm notlarına, gem başına CHANGELOG dosyalarına ve v8.1.3 ile v8.1.4 arasındaki commit karşılaştırmasına yönlendiriyor.
  • İndirilen gem’lerin kendi yüklediğiyle aynı olduğunu doğrulamak isteyenler için 13 gem’in SHA-256 özetini paylaşıyor.
  • Sürüm notlarına göre Action Mailbox, Action Text ve kılavuzlarda değişiklik yok. 176 değişikliğin 76’sı Kenta Ishizaki imzalı.
  • Duyuru, katkıda bulunan herkese teşekkürle bitiyor.

Active Support

  • Sayı biçimlendirme. number_to_human_size terabaytın üzerinde çöküyordu, petabayt, eksabayt ve zettabayt birimleri eklendi. :precision nil olduğunda üç yardımcı daha artık çökmüyor. number_to_delimited işaretli sayıları bozmuyor ve varsayılan olarak daha hızlı string tabanlı yolu kullanıyor. number_to_phone‘da alan kodu yokken ayırıcıyla ilgili iki hata giderildi.
  • Argüman değiştirme. transliterate, Time#advance ve Cache::Store#delete_multi artık kendilerine verilen string’i, hash’i ya da diziyi yerinde değiştirmiyor.
  • Cache. Local cache açıkken fetch_multi istenen anahtar sırasını koruyor. MemoryStore ve FileStore‘daki iki çökme giderildi. RedisCacheStore, sentinel kullanımı gibi durumlarda çevrilmeden gelen RedisClient::Error‘ı da yakalıyor.
  • Süre ve zaman. Duration#in_minutes ve benzerleri kesirli saniyeyi atıyordu: 90,5 saniye artık 1,5 değil yaklaşık 1,508 dakika ediyor. Zaman dilimleri güncel IANA adlarını kullanıyor: Europe/Kyiv ve Asia/Yangon.
  • JSON. ActiveSupport::JSON.decode, yakında çıkacak json 3.0 gem’iyle uyumlu hale getirildi. String olmayan hash anahtarlarında yeni encoder to_s yerine as_json çağırıyor, bu yüzden Time anahtarlarını eskisinden farklı yazıyordu.
  • Küçük yardımcılar. titleize Unicode harfleri doğru büyütüyor (“ćasim đipa” → “Ćasim Đipa”). parameterize nil ayırıcıyı boş ayırıcı gibi ele alıyor. HashWithIndifferentAccess#filter düz Hash yerine yine HWIA döndürüyor. in_order_of, truncate, Range#sole ve debug hata sayfasında da düzeltmeler var.

Active Model

  • DoS önlemi. Çok uzun string’lerde to_i yavaşladığı için bu yol saldırıya açıktı. Integer tipi artık yalnızca string’in ilk limit * 4 baytına bakıyor: varsayılan integer için 16, bigint için 32 bayt. Değişiklik Aaron Patterson ve Jean Boussier imzalı.
  • normalizes. JSON sütunları gibi veritabanı tipi farklı olan attribute’larda yerinde değişiklikleri görmüyordu. Kaydedilmemiş kayıtlarda ise her valid? çağrısında yeniden çalışıp idempotent olmayan normalizer’ların sonucunu katlıyordu. Artık yalnızca gerçek bir değişiklikte çalışıyor.
  • alias_attribute ve Errors#import‘taki iki küçük hata da kapatıldı.

Active Record: bağlantılar ve adapter’lar

  • MySQL deadlock’u. Eşzamanlı find_or_create_by çağrıları transaction içinde aynı kaydı geri okurken kilitlenebiliyordu. Okuma artık shared lock ile yapılıyor. Düzeltme create_or_find_by‘ı da kapsıyor (#54281).
  • Havuz. Preconnect ile reaper arasındaki yarış durumu, iki deadlock ve bir connection sızıntısı giderildi. Tek bir connection kapanırken hata verdiğinde havuzun geri kalanı artık ortada kalmıyor.
  • Zaman aşımı. Bakımdaki bir connection’ı bekleyen checkout, checkout_timeout ayarına bakmadan 100 saniyeye kadar bekleyebiliyordu. database.yml’deki keepalive: false da artık 600 saniyelik varsayılana düşmüyor.
  • Kesilen sorgular. Timeout ya da fiber iptaliyle yarıda kesilen bir sorgunun connection’ı havuza sağlam gibi dönüyor, sonraki kullanıcı ölü bir socket’e çarpıyordu. Artık kullanılmadan önce yeniden doğrulanıyor. MySQL’in 1046 hatası (veritabanı seçilmedi) de yeniden denenebilir sayılıyor.
  • Paralel testler. Test çalışmasından sonra sızan Pool Reaper thread’i havuzları ve dosya tanımlayıcılarını açık tutuyordu. Kapanışta artık havuzlar atılıyor ve thread sonlandırılıyor.
  • Adapter’lar ve yapılandırma. PostgreSQL notice’leri sonraki sorgulara sızmıyor. MySQL adapter’ları tabloları incelerken sütun başına sorgu atmıyor, ek sorgu yalnızca MariaDB’de ve tablo başına bir tane. Başarısız db: görevlerinin hata mesajlarından veritabanı parolası süzülüyor. DATABASE_URL‘deki seeds ve use_metadata_table boolean’a çevriliyor.

Active Record: composite primary key ve foreign key

  • Notlarda tekrar eden iki kusur var: kodun composite key’in yalnızca ilk sütununa bakması ve request parametresinden gelen string id’leri bileşen bileşen tipine çevirmemesi.
  • İlişkiler. belongs_to’da değişiklik takibi, presence validasyonu, touch, inverse eşleşmesi ve preload artık bütün key sütunlarına bakıyor. has_many ve has_one’da yeni kayıtlarda boş dönen ilişkiler, disable_joins ile boş dönen through ilişkileri ve Book.group(:order).count gibi gruplanmış hesaplardaki hata giderildi.
  • String id’ler. find birden çok string tuple ile sessizce boş dizi dönüyordu. book_ids= gibi writer’lar var olan kayıtlar için RecordNotFound fırlatıyor, reset_counters kaydı bulamıyordu.
  • Finder’lar. find_signed, delete, find([]), excluding, kısmi select sonrasında id ve açık select ile eager_load artık composite key’lerde doğru çalışıyor.

Active Record: migration’lar ve şema

  • Sütun default’ları geri alındı. 8.1.0’da default’lar önceden deserialize edilmeye başlamıştı. Jean Boussier’nin notuna göre bu, attribute tipi modelde sonradan değiştirildiğinde sorun çıkardı: boolean’ı küçük integer olarak tutan veritabanlarında default bir kez boolean’a çevrilince integer’a geri dönülemiyordu. Artık veritabanının döndürdüğü değer kalıyor, columns_hash["age"].default 0 değil “0” dönüyor (#58292).
  • Sıralama geri alındı. schema.rb’de sütunların alfabetik sıralanması, db:prepare ile production tablolarını yanlış oluşturduğu için kaldırıldı. Şema önbelleğindeki isme göre sıralama da 8.1 öncesi davranışa döndü.
  • Geri alınabilirlik. add_column(if_not_exists: true) ve remove_foreign_key(if_exists: true) artık geri alınabiliyor. Tipi verilmeyip seçenek verilen remove_column ise geri alınamaz sayılıyor, çünkü seçenekler tip sanılıyordu.
  • PostgreSQL. Şema dökümünde farklı şemalardaki aynı adlı enum’lar, başka şemadaki opclass’lar, INHERITS sırası ve çok satırlı exclusion constraint’ler düzeltildi. daterange, tsrange ve tstzrange default’ları db:schema:load‘da SyntaxError veren Ruby üretiyordu. Virgül içeren range sınırları okunurken bozuluyordu.
  • SQLite ve MySQL. Newline içeren index’ler ve rename_index sonrasında kısmi index koşulları korunuyor. MySQL index adlarını tırnak içine alıyor.
  • STI. Type sütunu yeniden eklendiğinde temizlenmeyen bir önbellek, sorguların STI koşulunu atlamasına yol açabiliyordu.

Active Record: sorgular, ilişkiler ve kayıtlar

  • update_all ve delete_all. Group ve having’i yok sayıp tablodaki bütün satırları güncelliyor ya da siliyorlardı. Artık yalnızca HAVING koşulunu sağlayan satırlara dokunuyorlar.
  • only_columns. Açık bir sütun listesi yerine SELECT * üretiyor, dışlanması gereken sütunları da seçebiliyordu.
  • in_order_of. Sütuna yazılamayan değerler (aralık dışı integer, bilinmeyen enum anahtarı) IS NULL eşleşmesine dönüşüp NULL satırları getiriyordu. Artık yok sayılıyorlar.
  • Hesaplamalar ve callback’ler. average ve gruplanmış sum, distinct: true‘yu yok sayıyordu. prepend: true ile tanımlanan after_commit ve after_rollback callback’leri belirli bir ayarla yanlış sırada çalışıyordu. pluck strict_loading ihlallerini görmüyordu.
  • Serileştirme. Native JSON sütunlarında ActiveRecord::Coders::JSON çift kodlama yapıyordu. Şifreli JSON fixture’ları çözülemiyordu. Zaman sütunu dolu kayıtlar MessagePack önbelleğine alınamıyordu.
  • Diğerleri. HABTM koşulları tam nitelikli yazılıyor. create_or_find_by yeniden denemede koşulları çoğaltmıyor. becomes, kaydın silinmek üzere işaretlenmiş olduğunu kaybetmiyor. Virtual alias attribute’larındaki bir performans gerilemesi giderildi (#57183).

Action View

  • Encoding. Gövdesi ASCII olan template’lerde ASCII olmayan strict locals default’ları bozuk karakterlerle çıkıyordu. Haml gibi handler’larda ASCII olmayan template’lerin digest’i alınırken hata oluşuyordu (#58203).
  • Formlar. week_field ISO yıl sınırlarında geçersiz değer üretmiyor. Nil değer içeren collection’larda radio ve checkbox label’ları input’larıyla eşleşiyor.
  • ActionView::TestCase#render yeniden belgelere uygun davranıyor. eager_load açıkken :ruby render tracker’ı ERB template’lerine kaydediliyor.

Action Pack

  • Host kontrolü. İzinli host bir portla tanımlıysa www.example.com:80:80 gibi fazladan port içeren Host başlıkları reddediliyor.
  • If-Modified-Since. RFC 9110’un kabul edilmesini istediği üç tarih biçiminden yalnızca biri anlaşılıyor, diğer ikisinde 304 yerine tam yanıt gidiyordu. Başlık artık Time.httpdate ile okunuyor.
  • url_for. Opsiyonel route parçalarında boş string de nil gibi atlanıyor: /locale//products/123 yerine /products/123 üretiliyor.
  • Streaming. IO.copy_stream ile response stream’ine yazmak TypeError veriyor, veriyi sessizce bozabiliyordu.
  • Diğerleri. Selenium 4.45’le başlayan “cannot find Chrome binary” hatası sistem testlerinde giderildi. ActionController::Live artık erken yüklenmiyor ve yeni bir load hook’u var. Routing DSL’in deprecated hash biçimine verilen false değerler artık sessizce düşmüyor.

Active Job, Action Mailer ve Action Cable

  • Active Job. Kuyruğa ekleme transaction sonrasına ertelendiğinde retry_job wait_until, queue ve priority seçeneklerini kaybediyordu. Başarılı yeniden eklemede eski enqueue_error temizleniyor. Hatadan sonra devam eden bir continuation’da resume_job istisnayı alıyor.
  • Autoload. perform_all_later ve deliver_all_later, ilgili modül yüklenene kadar kullanılamıyordu.
  • Action Mailer. ActionMailer::Base.mail 8.1’den beri MessageDelivery döndürmüyordu.
  • Action Cable. Redis adapter’ı redis-rb 6’yı kabul ediyor. PostgreSQL adapter’ı 63 baytlık sınırı karakterle ölçtüğü için çok baytlı stream adlarında yayınlar kayboluyordu.

Active Storage

  • image_processing 2.x. Bu sürümde ruby-vips ve mini_magick yumuşak bağımlılık oldu. Biri eksikse Active Storage hatayı tanımıyor, uyarı vermek yerine uygulamanın açılışını durduruyordu. Artık yalnızca uyarıyor (#58413).
  • Aynalama. MirrorService metadata’yı düşürdüğü için S3, Azure ve GCS’deki kopyalar application/octet-stream olarak sunuluyordu (#57270). Checksum’sız aynalama da hata veriyordu.
  • Video önizlemesi. Arka planda çalışan Rails sürecini ffmpeg, SIGTTOU sinyaliyle süresiz askıya alabiliyordu. ffmpeg’in stdin’ine artık /dev/null veriliyor.
  • Diğerleri. Attachment adı bir attribute’la çakıştığında to_json sonsuz özyinelemeye giriyordu. touch_attachment_records = false, STI dönüşümü ve dependent: :purge ile ilgili hatalar da kapatıldı (#36423).

Railties

  • Thread-safe route yüklemesi. eager_load kapalıyken, yani development ve test’te varsayılan olarak, route’lar ilk istekte çiziliyor. Eşzamanlı ilk istekler yarım çizilmiş route setine düşüp geçerli route’lar için 404 alabiliyordu. Artık ilk çizim bitene kadar bekliyorlar.
  • Tembel route seti. url_helpers Object’e eklendiğinde her respond_to? çağrısı yükleyiciyi tetikliyordu, artık yalnızca _path ve _url metotları tetikliyor. after_routes_loaded hook’ları sonsuz yeniden yüklemeye yol açmıyor. main_app gibi mount helper’ları, route’lar çizilmeden çağrıldığında yüklemeyi başlatıyor.
  • Komutlar. rails plugin foo bar geçersiz alt komutu yok sayıp “bar” adlı bir plugin oluşturuyordu, artık hata veriyor (#57430). rails generate, null: false attribute’lar için ! değiştiricisini yazıyor. secret_key_base= hata mesajı hatalı değeri de gösteriyor.