Rails CHANGELOG "2019-10-01".."2019-10-06"

この期間の CHANGELOG.md へのコミットは5件。

ActiveRecordに関して2件、ActiveStorageに関して3件。

ActiveRecord

has_secure_token に文字数を指定できるようになった

コミット: Merge pull request #35915 from bernardoamc/allow-has-secure-token-len… · rails/rails@a273da7

もともとは24文字で固定だった。24文字以上の文字数を指定できるようになったので、セキュリティ的な要件で「めっちゃ長くしたい」場合もこれで安心。

Before:

has_secure_token :auth_token

After:

has_secure_token :default_token             # 24 characters
has_secure_token :auth_token, length: 36    # 36 characters
has_secure_token :invalid_token, length: 12 # => ActiveRecord::SecureToken::MinimumLengthError

引用: rails/activerecord/CHANGELOG.md at a273da7619ac6a2b2f98532a5610238c68ad219b · rails/rails

belongs_toinverse_of: オプションを has_many associationでも使えるようになった

コミット: Add support for belongs_to to has_many inversing. · rails/rails@d45c9ad

もともと belongs_toinverse_of: オプションは has_one associationにしか対応していなかった。これを has_many の場合でも使えるようになった。

たぶんこんな感じ(動作確認はしてない)

class User < ApplicationRecord
  has_many :writings,
           class_name: 'Book'
end
 
class Book < ApplicationRecord
  belongs_to :author,
             class_name: 'User',
             foreign_key: 'author_id'
             # ここに inverse_of: 'writings' を指定できるようになった。 
end

ActiveStorage

添付ファイルごとに保存先の外部サービスを選べるようになった

コミット: Allow configure services for individual attachments · rails/rails@e7f798c

ActiveStorageあまり触っていなくてよく分からん太郎だったのでRailsガイドで復習した。Active Storage の概要 - Rails ガイド

「セットアップ」に書かれているようにActiveStorageで使うサービスは config/storage.yml で定義して、環境ごとに config/environments/ 配下で設定する。これだと同一環境内で使えるサービスは1つだけになる。例えば「production では Amazon S3 を使う!!!1」など。

で、今回のコミットでは添付ファイルごとに保存先のサービスを選べるようになるよ、便利だね、という話。

class User < ActiveRecord::Base
  has_one_attached :avatar, service: :s3
end
class Gallery < ActiveRecord::Base
  has_many_attached :photos, service: :s3
end

引用: rails/activestorage/CHANGELOG.md at e7f798c3f549502d696167e9b29f18106cf2cbe0 · DmitryTsepelev/rails

active_storage_blobs テーブルに service_name カラムが追加されているからversion upの際にはmigrationが必要になりそう。

外部サービスに画像のvariantをアップロードするときにContent-Typeを指定するようになった

コミット: Set Content-Type on variant uploads · rails/rails@698e9ce

Content-Typeが指定されていなかったので指定したよ、というコミット。

Content-Typeは delegate :filename, :content_type, :format, to: :specification となっていて specification はこうなってた。

def specification
  @specification ||=
    if WEB_IMAGE_CONTENT_TYPES.include?(blob.content_type)
      Specification.new \
          filename: blob.filename,
          content_type: blob.content_type,
          format: nil
    else
      Specification.new \
          filename: ActiveStorage::Filename.new("#{blob.filename.base}.png"),
          content_type: "image/png",
          format: "png"
    end
end

引用: rails/variant.rb at 698e9ce0ffb516564e02053872077a2d5a287617 · rails/rails

ので、Content-Typeは WEB_IMAGE_CONTENT_TYPES(= %w[ image/png image/jpeg image/jpg image/gif ]) のどれか or "image/png" になる。

明示的にサービス名を指定しなくてもよくなった

コミット: Make Active Storage services aware of configuration names · rails/rails@e6487e8

1つ目の 添付ファイルごとに保存先の外部サービスを選べるようになった に関連する修正。

ActiveStorage::Service::Configurator クラスをbuildするときに config/storage.yml に指定されているサービス名を使うよう修正されている

def build(service_name)
  config = config_for(service_name.to_sym)
  resolve(config.fetch(:service)).build(
    **config, configurator: self, name: service_name
  )
end

引用: rails/configurator.rb at e6487e84fc0dae30d3b20b396404881e962f1f3a · rails/rails

で、ActiveStorage::Service クラスにインスタンス変数 name が追加され、has_one_attached :avatar, service: :s3 のようにサービスが指定された時だけ、その値で上書きする、という感じになっている

def build(configurator:, name:, service: nil, **service_config) #:nodoc:
  new(**service_config).tap do |service_instance|
    service_instance.name = name
  end
end

引用: rails/service.rb at e6487e84fc0dae30d3b20b396404881e962f1f3a · rails/rails