こんにちは、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を実行する
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を実行する
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
参考