1
5

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 5 years have passed since last update.

[学習用]Rails5:CarrierWaveで画像投稿+rmagickでサムネイル保存+画像名ランダム化

Last updated at Posted at 2019-03-07

うっかり忘れたので構築した手順を忘れない様にメモ。
※ローカルテスト用。Herokuには保存できないので、AWSのS3に保存するときは
 保存先を違うものに変更する必要がある。

#scaffold で一括作成

$ rails g scaffold shop title:string content:text name:string cat_id:integer user_id:integer image:string

まず、scaffold で一括作成。

ハマったポイント

このときimage:string も一緒に作ってしまう。
ここを忘れてて、画像が登録されないerrorに悩まされる。

###もし追加し忘れたら

$ rails g migration add_image_column_to_shops image:string
$ rails db:migrate

これで大丈夫。

#Gem CarrierWaveの追加

gem 'carrierwave'

Gemfile に上記を追加して

$ bundle

#アップローダークラス生成

$ rails g uploader image

app/uploader/image_uploader.rb が作成される

##CarrierWave編集

app/uploaders/image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
  storage :file
  # storage :fog

  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

  def extension_whitelist
    %w(jpg jpeg gif png)
  end
  # 画像名をリネームさせる(日付時間はダメ絶対)
  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

end

###はまったポイント
"#{Time.zone.now.strftime('%Y%m%d%H%M%S')}.jpg" if original_filename.present?
タイムゾーンにするとリサイズ時にエラーが出てサイズの変更ができなくなる。
エラー名が全然違うので、全くわからなかった。
RMagick入ってないよとかMiniMagick入ってないよとかそんなerrorが出てテンパる。

##追加

/app/models/shop.rb
class Shop < ApplicationRecord
  mount_uploader :image, ImageUploader
end

#パラメータの確認

/app/controllers/posts_controller.rb
  private
    # Use callbacks to share common setup or constraints between actions.
    def set_shop
      @shop = Shop.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def shop_params
      params.require(:shop).permit(:title, :content, :cat_id, :name, :user_id, :image)
    end

image をscaffoldより後から追加したなら :imageを追加する。
image をscaffoldで追加したなら入っているか確認する。

#画像が表示できる様にする
##画像を登録

/app/views/_form.html.erb

  <%= form.label :image %>
  <%= form.file_field :image %>

変更、新規、編集の時に追加できるように。

#表示側の追加

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

#画像のリサイズ

gem 'rmagick'
$ bundle

##CarrierWave編集

app/uploaders/image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
  # Include RMagick or MiniMagick support:
  include CarrierWave::RMagick
  # include CarrierWave::MiniMagick

  # Choose what kind of storage to use for this uploader:
  storage :file
  # storage :fog

  # Override the directory where uploaded files will be stored.
  # This is a sensible default for uploaders that are meant to be mounted:
  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

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

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

  # サムネイル保存する
  version :thumb do
    process :resize_to_limit => [320, 320]
  end

  # 保存形式
  process :convert => 'jpg'

  def extension_whitelist
    %w(jpg jpeg gif png)
  end

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

  # ファイル名を日付にすると不具合が出る
  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
end

##Viewにサムネイル追加

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

<%= image_tag @shop.image.url(:thumb) %>

これで640画像と320のサムネイル画像が表示される
これで忘れても大丈夫なはず。

参考にしたサイト
https://nyoken.com/rails-carrierwave

1
5
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
1
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?