【CarrierWave】Railsで画像をアップロードするカンタンな方法は?

スポンサーリンク

 

こんにちは、Railsエンジニアにょけん(@nyoken_box)です。

「Railsで画像アップロード機能を実装したい!」って場面、あなたにもあるでしょうか?

本記事では、カンタンに実装する手順を紹介しています。

サンプルとして、今回はTwitterのようなSNSアプリで、投稿時に画像を追加する処理を実装してみましょう。

投稿をするための「Postsコントローラー・Postsクラス」が存在していて、ここに画像アップロード用の処理を追加していく想定です。

 

スポンサーリンク

gem「CarrierWave」で、画像アップロード機能を実装

①画像アップロード用のカラム(名前は通常”image”カラム)をデータベースに追加する

[ターミナル]
rails g migration add_image_column_to_posts image:string

どの画像を表示するのかを指定するために、データベースに画像ファイル名を格納しておく必要があるんですね。

上記では例として、Postsテーブルにimageカラムを追加しています。

お使いのアプリに応じて変更してください。(ユーザーのプロフィール画像を設定させたいなら、Usersテーブルに追加してあげたりとか?)

 

Gemfileに’carrierwave’を追加して、bundle installを実行する

[/Gemfile]
gem 'carrierwave'

 

[ターミナル]
bundle install

 

③「rails g uploader アップローダー名」で、アップローダー(画像アップロード用の機能)クラスを生成する

[ターミナル]
rails g uploader image

上記を実行することで,「app/uploader/image_uploader.rb」がつくられます。

アップローダーっていうのは、こんな感じのやつですね。

 

④アップローダーを実装したいクラス(ここではPostクラス)に、以下のコードを記述

[/app/models/post.rb]
mount_uploader :image, ImageUploader

上記を実行することで、アップローダーを実装できます。

ここでは例として、「post.rb」に実装しました。

 

⑤ストロングパラメーターに「imageカラム」を追加する

Postsコントローラーにて、ストロングパラメーターの設定を変更します。

ストロングパラメーターについては、以下をご覧ください。

参照:「Strong Parameterの基本的な仕組みと使い方は?」

 

[/app/controllers/posts_controller]
  def create
    @post = current_user.posts.build(post_params)
    if @post.save
      flash[:success] = "Post created!"
      redirect_to root_url
    end
  end

private
  def post_params
    params.require(:post).permit(:content, :image)
  end

ピンク色の部分が、ストロングパラメーターに関する部分ですね。

 

⑤アップローダーを実装したいviewと、画像を表示したいviewを編集する

・投稿を作成するviewにて、アップローダー表示用の以下コードを追加。

[/app/views/new.html.erb]
<%= f.label "画像をアップロード" %><br><%= f.file_field :image %>

この記述によって、アップローダーが表示されます。

よくあるやつですね。

「ファイルを選択」から画像を選んでアップロードすると、「public/uploads/post/image/:postのID/ファイル名」に保存される。

 

・投稿を表示するviewにて、画像表示用の以下コードを追加。

[/app/views/show.html.erb]
<% if @post.image? %>
    <%= image_tag @post.image.url %>
<% end %>

 

スポンサーリンク

gem「Rmagick」で画像サイズを調整する

画像をちょうど良いサイズで表示するために、「rmagick」というgemを使います。

 

imageMagickをインストールする

これをインストールしないと、Rmagickがインストールできません

以下のコマンドでインストールしましょう。

 

・Cloud9の場合

sudo yum -y install ImageMagick ImageMagick-devil

 

・Macの場合

brew install imagemagick@6
brew link --force imagemagick@6

 

Gemfileに’rmagick’を追加して、bundle installを実行する

[/Gemfile]
gem 'rmagick'

 

[ターミナル]
bundle install

 

③「app/uploaders/image_uploader.rb」を編集する

アップロードした画像について、詳細設定を行う。

いろいろ設定できるので、以下を参考に必要なものを実装してみましょう。

[app/uploaders/image_uploader.rb]
class ImageUploader < CarrierWave::Uploader::Base

# リサイズしたり画像形式を変更するのに必要
  include CarrierWave::RMagick

# アップローダーでどんな種類のものを受け取るか指定
  storage :file

# ファイルサイズに制限をつける
  def size_range
    1..5.megabytes
  end

# 画像の上限を640x480にする
  process :resize_to_limit => [640, 480]

# 保存形式をJPGにする
  process :convert => 'jpg'

# アップロード時に、300*300サイズのサムネイルも保存する
  version :thumb do
    process :resize_to_limit => [300, 300]
  end

# jpg,jpeg,gif,pngしか受け付けない
  def extension_whitelist
    %w(jpg jpeg gif png)
  end

# 拡張子が同じでないとGIFをJPGとかにコンバートできないので、ファイル名を変更
  def filename
    super.chomp(File.extname(super)) + '.jpg' if original_filename.present?
  end

# ファイル名を日付にすると編集時のデータ受け渡し等で不具合が出るため、ファイル名をランダムで一意にsuる
  def filename
    "#{secure_token}.#{file.extension}" if original_filename.present?
  end

protected
  def secure_token
    var = :"@#{mounted_as}_secure_token"
    model.instance_variable_get(var) or model.instance_variable_set(var, SecureRandom.uuid)
  end


# アップロードされたファイルを保存するディレクトリをデフォルトに設定する
  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

 

参考

スポンサーリンク