0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ActiveStorageを使って画像アップロードする

0
Posted at

環境

  • OS: macOS 12.3.1(21E258)
  • Ruby: 3.1.3
  • Rails: 7.0.4

Railsアプリの作成する

rails new images

Active Storageのインストール

rails active_storage:install
Copied migration 20221227045939_create_active_storage_tables.active_storage.rb from active_storage

マイグレーション

rails db:create db:migrate
Database 'db/development.sqlite3' already exists
Database 'db/test.sqlite3' already exists
== 20221227045939 CreateActiveStorageTables: migrating ========================
-- create_table(:active_storage_blobs, {:id=>:primary_key})
   -> 0.0010s
-- create_table(:active_storage_attachments, {:id=>:primary_key})
   -> 0.0008s
-- create_table(:active_storage_variant_records, {:id=>:primary_key})
   -> 0.0005s
== 20221227045939 CreateActiveStorageTables: migrated (0.0023s) ===============

最初の画面を作る

今回は写真を投稿する画面を1つだけ作る。

  • routes.rbにrootを追加
Rails.application.routes.draw do
  # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html

  root "posts#new"
end
  • app/controllers/posts_controller.rbを作成
class PostsController < ApplicationController
  def new
  end
end
  • app/views/posts/new.html.erbを作成
<h1>Example Image Uploader</h1>

動作確認

bin/rails s

画像を保持するモデルを作成

ここでは、Post(投稿)というモデルを作って、1つのPostに対して複数の写真(photos)をアップロードできるようにする。

rails g model Post                                             
      invoke  active_record
      create    db/migrate/20221227051214_create_posts.rb
      create    app/models/post.rb
      invoke    test_unit
      create      test/models/post_test.rb
      create      test/fixtures/posts.yml
  • app/models/post.rbを開き、has_many_attachedを追加
class Post < ApplicationRecord
  has_many_attached :photos
end

マイグレーションを実行する

rails db:migrate

== 20221227051214 CreatePosts: migrating ======================================
-- create_table(:posts)
  TRANSACTION (0.1ms)  begin transaction
   (1.7ms)  CREATE TABLE "posts" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "created_at" datetime(6) NOT NULL, "updated_at" datetime(6) NOT NULL)
   -> 0.0041s
== 20221227051214 CreatePosts: migrated (0.0042s) =============================

画面にアップロードするフォームを作成

  • app/views/posts/new.html.erb
<h1>Example Image Uploader</h1>

<%= form_with model: @post do |f| %>
  <%= f.file_field :photos %>
  <%= f.submit %>
<% end %>

動作確認する。こんな感じで表示される。

Images (1)

アップロードの処理を書く

  • config/routes.rbにPOST /postsのルーティングを追加
Rails.application.routes.draw do
  # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html

  # Defines the root path route ("/")
  root "posts#new"

  resources :posts, only: [:new, :create]
end
  • app/controllers/post_controller.rbを作成。#newメソッドと#createメソッドを書く
class PostsController < ApplicationController

  def new
    @post = Post.new
  end

  def create
    @post = Post.new(post_params)
    @post.save
    redirect_to root_path
  end

  private
  
  def post_params
    params.require(:post).permit(:photos)
  end
end

Postにフィールドを追加する

バリデーションエラーが発生した場合の動作のチェックのためにPostモデルにフィールドを追加する。
ここではタイトル(title)という文字列フィールドを追加することにする。タイトルは20文字を超えるとバリデーションでエラーになるようにする。

rails g migration AddTitleColumnToPosts
  • config/db/..._add_title_column_to_posts.rb
class AddTitleColumnToPosts < ActiveRecord::Migration[7.0]
  def change
    add_column :posts, :title, :string
  end
end
  • マイグレーション
rails db:migrate
== 20221227054700 AddTitleColumnToPosts: migrating ============================
-- add_column(:posts, :title, :string)
   -> 0.0010s
== 20221227054700 AddTitleColumnToPosts: migrated (0.0010s) ===================
  • app/models/post.rb

バリデーションを追加

class Post < ApplicationRecord
  has_many_attached :photos

  validates :title, presence: true, length: { maximum: 20 } # ここを追加
end

  • app/controllers/posts_controller.rb

バリデーションエラーの時はリダイレクトではなく、renderするように変更

...
  def create
    @post = Post.new(post_params)
    if @post.save
      redirect_to new_post_path
    else
      render :new, status: 400
    end
  end
  ...
  • app/views/posts/new.html.erb

画面にバリデーションエラーの表示を追加

<h1>Example Image Uploader</h1>

<%= form_with model: @post do |f| %>
  <ul>
    <% @post.errors.full_messages.each do |m| %>
      <li><%= m %></li>
    <% end %>
  </ul>
  <div><%= f.text_field :title %></div>
  <div><%= f.file_field :photos %></div>
  <div><%= f.submit %></div>
<% end %>
0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?