Ruby on Railsで画像ファイルのアップロード(超簡単)

Ruby on Railsで画像ファイルのアップロード(超簡単)

Ruby on Railsで画像のアップロードを実現する方法です。

今回はユーザーのアイコン画像登録を行います。

 

環境は以下の通りです。

・ruby :2.5.3
・rails :5.2.1

 

「画像を保存する」手順としては

  1. gemの「carrierwave」をインストール
  2. アップローダーの作成
  3. ユーザーモデルに画像のパスを格納するカラムの追加
  4. ユーザーモデルにアップローダーへマウントする記述を追加
  5. ビューでフォーム作成
  6. コントローラーで保存処理

という流れになります。

 

非常に簡単で、5分もあれば十分できると思いますので

サクっとやっていきましょう!

 

1.gemのcarrierwaveをインストール

Gemfileに以下の一文を追加して、bundle installをしましょう。

gem 'carrierwave'
$bundle install

インストールが完了すれば 1. は終わりです。

 

 

2.アップローダーの作成

 

ターミナルから以下のコマンドを入力し、アップローダーを作成します。

$rails g uploader image

image部分は好きな名前にしてください。

これで 2. は終わりです。

 

 

3.ユーザーモデルに画像のパスを格納するカラムの追加

 

以下のコマンドを入力してカラムを追加しましょう。

$rails g migration AddImageToUsers image:string

db/migrate/(日付)_add_image_to_users.rb というファイルができます。何も変更する必要はないですが、一応見ておくと、以下のようになっていると思います。

class AddImageToUsers < ActiveRecord::Migration[5.2]
  def change
    add_column :users, :image, :string
  end
end

これをデータベースに反映させるためにマイグレーションをしておきましょう。

$rails db:migrate

これで 3. は完了です。

 

4.ユーザーモデルにアップローダーへマウントする記述を追加

 

次はmodelsのuser.rbファイルに以下の一文を追加します。

class User < ApplicationRecord
     ...
     mount_uploader :image, ImageUploader # これを追加
end

これで 5. は完了です。これで画像を保存するために必要なものは揃いました。あとはコントローラーとビューで書いてやるだけです。

 

 

5.ビューでフォーム作成

 

ユーザーの画像を保存するのはユーザー情報の編集画面、editのアクションだと思いますので、editのビューでフォームの画像送信を追加します。以下に画像の変更だけのフォーム送信のサンプルをおいておきます。

 

<%= form_with(model: @user, url: user_path, method: :put, local: true) do |f| %>
  <% if @user.image? %>
     <%= image_tag @user.image.url %>
  <% else %>
     画像が登録されていません。
  <% end %>
  <%= f.file_field :image %>
  <%= f.submit '画像をアップロードする' %>
<% end %>

これで簡単な画像登録用のフォームができました。

(上の例では@userとあるようにログインしているユーザーの情報をコントローラーのeditアクションで@user変数に入れておかないとエラーになります。)

 

ここではフォームの送信先をuser_pathにしてput送信をしているので、ルーティングの情報を

$rails routes

このコマンドで見ると以下のようになっていることから、

users      GET /users(.:format) users#index
         POST /users(.:format) users#create
new_user    GET /users/new(.:format) users#new
edit_user   GET /users/:id/edit(.:format) users#edit
user        GET /users/:id(.:format) users#show
            PATCH /users/:id(.:format) users#update
            PUT /users/:id(.:format) users#update     // ←これ
            DELETE /users/:id(.:format) users#destroy

コントローラーのupdateアクションに保存処理を書いていけばよいことになります。

 

 

6.コントローラーで保存処理

 

それでは users_controller.rb の update アクションに保存処理を書いていきましょう。

まず先にストロングパラメーターにimageカラムを追加しておきます。

 def user_params
      params.require(:user).permit(:email, :user_name, :password, :password_confirmation, :image) // :imageを追加
 end

 

それから保存処理を書きます。

def update 
   @user = User.find(params[:id])
   # ログインしているユーザーかどうか判断
   if current_user == @user
     if @user.update(user_params)
       flash[:success] = 'ユーザー情報を編集しました。'
       render :edit
     else
       flash.now[:danger] = 'ユーザー情報の編集に失敗しました。'
       render :edit
     end
   else
       redirect_to root_url
   end
end

これで完了です!

あとは実際に画面でアップロードをしてみましょう!

flashを書いているので成功すれば画面上部に「ユーザー情報を編集しました。」という文字が出ます。失敗すれば「ユーザー情報の編集に失敗しました。」という文字が出ます。

 

 

上手くいかないときは….?

もし画像登録が上手くいかないときは以下の点を確認してみるといいかもしれません。

・今回は画像をアップロードした際に、ユーザーのimageカラムのパスのみを更新していることになるので、更新時にパスワードなどのバリデーションが有効になっている場合はバリデーションにひっかかってしまい更新が出来ません。

・またファイル名が日本語の場合は上手くいかないかもしれないので英語に直してみましょう。

 

 

実際にやってみると以下のように表示されている画面から

ファイルを選択してアップロードしてみると、

 

 

同じ画面に帰ってきてアップロードした画像が表示されています。

ちなみに保存された画像は

public/uploads/user/image/(数字)のディレクトリに保存されているので確認しておきましょう!