うっかり忘れたので構築した手順を忘れない様にメモ。
※ローカルテスト用。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編集
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が出てテンパる。
##追加
class Shop < ApplicationRecord
mount_uploader :image, ImageUploader
end
#パラメータの確認
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で追加したなら入っているか確認する。
#画像が表示できる様にする
##画像を登録
<%= form.label :image %>
<%= form.file_field :image %>
変更、新規、編集の時に追加できるように。
#表示側の追加
<% if @shop.image? %>
<%= image_tag @shop.image.url %>
<% end %>
#画像のリサイズ
gem 'rmagick'
$ bundle
##CarrierWave編集
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にサムネイル追加
<% if @shop.image? %>
<%= image_tag @shop.image.url %>
<% end %>
<%= image_tag @shop.image.url(:thumb) %>
これで640画像と320のサムネイル画像が表示される
これで忘れても大丈夫なはず。
参考にしたサイト
https://nyoken.com/rails-carrierwave