neutral2010 / log

作業用のissueを立てるためのリポジトリ
0 stars 0 forks source link

Railsアプリにユーザーのアイコン画像アップロードの機能を追加 #4

Open neutral2010 opened 2 years ago

neutral2010 commented 2 years ago

ActiveStorageで画像アップロードを実装する

neutral2010 commented 2 years ago

ファイルをレコードに添付する

has-one-attached

neutral2010 commented 2 years ago

セットアップ

  1. rails active_storage:install
  2. 3つのテーブルを作るマイグレーションファイルができる
    • active_storage_blobs:Blobモデルは添付ファイル(attachment)のメタデータ(ファイル名やコンテンツの種類など)と識別子のキーをストレージサービスに保存
    • active_storage_attachments:使うモデルのクラス名を保存するポリモーフィックjoinテーブル
    • (active_storage_variant_records)
  3. rails db:migrate
ruby~/fBootcamp/fjord-books_app my-user_icon*
❯ bundle install
.
.
.

Bundle complete! 27 Gemfile dependencies, 106 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.

~/fBootcamp/fjord-books_app my-user_icon*
❯ rails active_storage:install
Copied migration 20220407124851_create_active_storage_tables.active_storage.rb from active_storage
# Store uploaded files on the local file system (see config/storage.yml for options)
config.active_storage.service = :local

画像をリサイズするためのgem

gem 'mini_magick', '~> 4.11' mini_magick | RubyGems.org | コミュニティのGemホスティングサービス

neutral2010 commented 2 years ago

設定の確認

✔︎ `config/storage.yml :ファイルの格納先を宣言

test:
  service: Disk
  root: <%= Rails.root.join("tmp/storage") %>

local:
  service: Disk
  root: <%= Rails.root.join("storage") %>

✔︎ config/environments/development.rb:利用するサービスをActive Storageに認識させる

neutral2010 commented 2 years ago

バリデーションの設定

ActiveStorageにはバリデーションの機能がない

  1. aki77/activestorage-validator: ActiveStorage blob validator.
    validates :icon, presence: true, blob: { content_type: ['image/png', 'image/jpg', 'image/jpeg'] }
  2. https://github.com/igorkasyanchuk/active_storage_validations
    lidates :icon, content_type: [:jpg, :png, :gif]
  3. htmlの属性で制限する
    <%= f.file_field :avatar, accept: "image/jpg,image/png,image/gif" %>

    1.や2.のgemを使った場合、エラーメッセージは自分で付ける?

エラーだった。

# app/views/devise/registrations/_profile_fields.html.erb
<div class="field">
  <%= f.label :icon %>
  <% if @user.icon.attached? && @user.icon.variable? %>
    <%= image_tag @user.icon.variant(resize_to_fill: [50, 50]) %>
  <% end %>
  <%= f.file_field :icon %>
</div>
neutral2010 commented 2 years ago

N+1

with_attached_nameを使う

# app/controllers/users_controller.rb
  def index
    @users = User.with_attached_avatar.order(:id).page(params[:page])
  end

ログの量が全然違う!

neutral2010 commented 2 years ago

リサイズするための書き方

Rails 6.0の "Active Storage's ImageProcessing transformer doesn't support :combine_options" という警告に対処する方法 - Qiita