LoginSignup
3
3

【WIP】Rails7.1での変更点

Posted at

こんにちは。プログラミングスクールHappiness Chainでメンターをしているryoです。
今回は、最近リリースされたRails7.1の変更点に関して、記載していきます。

※以下公式リリースノートの和訳と、個人的な感想を少し記載しています。

※ こちら執筆途中になりますので、ご了承ください。

Railsアプリ新規作成時に、Dockerfileの自動生成

rails new sample-projectをすると以下のDockerfileが自動生成される。

# syntax = docker/dockerfile:1

# Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile
ARG RUBY_VERSION=3.2.2
FROM registry.docker.com/library/ruby:$RUBY_VERSION-slim as base

# Rails app lives here
WORKDIR /rails

# Set production environment
ENV RAILS_ENV="production" \
    BUNDLE_DEPLOYMENT="1" \
    BUNDLE_PATH="/usr/local/bundle" \
    BUNDLE_WITHOUT="development"


# Throw-away build stage to reduce size of final image
FROM base as build

# Install packages needed to build gems
RUN apt-get update -qq && \
    apt-get install --no-install-recommends -y build-essential git libvips pkg-config

# Install application gems
COPY Gemfile Gemfile.lock ./
RUN bundle install && \
    rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git && \
    bundle exec bootsnap precompile --gemfile

# Copy application code
COPY . .

# Precompile bootsnap code for faster boot times
RUN bundle exec bootsnap precompile app/ lib/

# Precompiling assets for production without requiring secret RAILS_MASTER_KEY
RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile


# Final stage for app image
FROM base

# Install packages needed for deployment
RUN apt-get update -qq && \
    apt-get install --no-install-recommends -y curl libsqlite3-0 libvips && \
    rm -rf /var/lib/apt/lists /var/cache/apt/archives

# Copy built artifacts: gems, application
COPY --from=build /usr/local/bundle /usr/local/bundle
COPY --from=build /rails /rails

# Run and own only the runtime files as a non-root user for security
RUN useradd rails --create-home --shell /bin/bash && \
    chown -R rails:rails db log storage tmp
USER rails:rails

# Entrypoint prepares the database.
ENTRYPOINT ["/rails/bin/docker-entrypoint"]

# Start the server by default, this can be overwritten at runtime
EXPOSE 3000
CMD ["./bin/rails", "server"]

本番環境にチューニングされたチューニングされたDockerfile(適切なlayer、image sizeを最小化するためにmulti-stage buildの利用)ということで、実際にrails newしましたけど、multi-stage buildの記載になってたり、bootsnapでのpre compileとassetのprecompileなど既に記載されてて、そこまでDockerfileをいじる必要なさそう。

独自の認証機能の改善された

has_secure_passwordを保管するための機能として以下の通り。

  • normalizes
    • カラムを保存時に正規化してくれる(検索時も)
user = User.create(email: " CRUISE-CONTROL@EXAMPLE.COM\n")
user.email                  # => "cruise-control@example.com"

user = User.find_by(email: "\tCRUISE-CONTROL@EXAMPLE.COM ")
user.email                  # => "cruise-control@example.com"
  • authenticate_by
    • パスワード以外のカラムでレコードを見つけ、パスワードで認証し、成功の場合は、レコードを返し、失敗の場合nilを返す(受け取ったパスワードは常にdigest化する)
    • これにより、ブルーフォース攻撃の軽減となる
class User < ActiveRecord::Base
  has_secure_password
end

User.create(name: "John Doe", email: "jdoe@example.com", password: "abc123")

User.authenticate_by(email: "jdoe@example.com", password: "abc123").name # => "John Doe" (in 373.4ms)
User.authenticate_by(email: "jdoe@example.com", password: "wrong")       # => nil (in 373.9ms)
  • generates_token_for
    • passwordをリセットする際に使うようなtokenを発行することができる。
class User < ApplicationRecord
  has_secure_password

  generates_token_for :password_reset, expires_in: 15.minutes do
    # Last 10 characters of password salt, which changes when password is updated:
    password_salt&.last(10)
  end
end

user = User.first

token = user.generate_token_for(:password_reset)
User.find_by_token_for(:password_reset, token) # => user
# 16 minutes later...
User.find_by_token_for(:password_reset, token) # => nil

has_secure_passwordに関しては、
パスワード更新時に、自動的に検証できるようになった
passwordに新しいパスワード、password_challengeに現在のパスワードを渡すことで、パスワードの更新が可能)
# Schema: User(name:string, password_digest:string)
class User < ActiveRecord::Base
  has_secure_password
end

user = User.new(name: "rafael", password: "railsrocks", password_confirmation: "railsrocks")
user.save                                                                      # => true
user.update(password: "pwn3d", password_challenge: "")                         # => false, challenge doesn't authenticate
user.update(password: "railsGetsEvenBetter", password_challenge: "railsrocks") # => true
  • has_secure_password
    • パスワード更新時に、自動的に検証できるようになった
      (passwordに新しいパスワード、password_challengeに現在のパスワードを渡すことで、パスワードの更新が可能)
# Schema: User(name:string, password_digest:string)
class User < ActiveRecord::Base
  has_secure_password
end

user = User.new(name: "rafael", password: "railsrocks", password_confirmation: "railsrocks")
user.save                                                                      # => true
user.update(password: "pwn3d", password_challenge: "")                         # => false, challenge doesn't authenticate
user.update(password: "railsGetsEvenBetter", password_challenge: "railsrocks") # => true

rails標準の認証が、以前よりも楽にセキュアに書けるようになった印象。

非同期クエリサポートの拡張

遅いクエリ、特に計算に重点を置いたクエリを、非同期で実行できるようになった。
追加されたメソッドは以下の通り。

  • async_count
  • async_sum
  • async_minimum
  • async_maximum
  • async_average
  • async_pluck
  • async_pick
  • async_ids
  • async_find_by_sql
  • async_count_by_sql

これはとてもありがたい。

現在執筆中です🙇

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3