ruby-on-rails - 使用 Google Cloud Storage 和 Carrierwave 保存图像时出错
问题描述
我使用carrierwave、fog和AWS S3来保存我的图像,
但我需要将这种方式更改为 Google Cloud Storage。
我找到了雾谷歌的一些方法,但这已经过时了。
所以我用没有雾的carrierwave-google-storage gem尝试了这个,
但效果不佳。
我在carrierwave-google-storage git页面中做了完全相同的过程。
(链接:https ://github.com/metaware/carrierwave-google-storage )
我附上了我的 image_uploader.rb、carrierwave.rb 和日志消息。
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 :gcloud
# 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
# Provide a default URL as a default if there hasn't been a file uploaded:
# def default_url(*args)
# # For Rails 3.1+ asset pipeline compatibility:
# # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
#
# "/images/fallback/" + [version_name, "default.png"].compact.join('_')
# end
# Process files as they are uploaded:
# process scale: [200, 300]
#
# def scale(width, height)
# # do something
# end
# Create different versions of your uploaded files:
# version :thumb do
# process resize_to_fit: [50, 50]
# end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
def extension_whitelist
%w(jpg jpeg gif png)
end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
# def filename
# "something.jpg" if original_filename
# end
end
载波.rb
CarrierWave.configure do |config|
config.storage = :gcloud
config.gcloud_bucket = 'fullout-linemanager-storage'
config.gcloud_bucket_is_public = false
config.gcloud_authenticated_url_expiration = 600
# config.gcloud_content_disposition = 'attachment' // or you can skip this
config.gcloud_attributes = {
expires: 600
}
config.gcloud_credentials = {
gcloud_project: "fullout-test",
gcloud_keyfile: "../fullout-test-01ed5e95d6fd.json"
}
end
开发日志
(...)
app/controllers/application_controller.rb:13:in `render_500'
Started POST "/api/reactions" for ::1 at 2020-01-31 11:31:35 +0900
Processing by Api::ReactionsController#create as JSON
Parameters: {"name"=>"1", "reaction_type"=>"image", "contents"=>"[ NO TEXT ]", "tag"=>"ALL", "image"=>#<ActionDispatch::Http::UploadedFile:0x00007fc4b8976a38 @tempfile=#<Tempfile:/var/folders/jb/qnz4lt193kz7wzj06xrp9q5w0000gn/T/RackMultipart20200131-12922-1n5x9ks.png>, @original_filename="disney2500.png", @content_type="image/png", @headers="Content-Disposition: form-data; name=\"image\"; filename=\"disney2500.png\"\r\nContent-Type: image/png\r\n">}
[1m[36mUser Load (0.5ms)[0m [1m[34mSELECT `users`.* FROM `users` WHERE `users`.`id` = 1 ORDER BY `users`.`id` ASC LIMIT 1[0m
↳ app/controllers/api/reactions_controller.rb:188
Unpermitted parameter: :format
[1m[36mOption Load (0.3ms)[0m [1m[34mSELECT `options`.* FROM `options` WHERE `options`.`id` IS NULL LIMIT 1[0m
↳ app/controllers/api/reactions_controller.rb:63
[1m[35m (0.5ms)[0m [1m[35mBEGIN[0m
↳ app/controllers/api/reactions_controller.rb:64
[1m[36mReaction Create (0.5ms)[0m [1m[32mINSERT INTO `reactions` (`name`, `contents`, `reaction_type`, `channel_id`, `tag`, `target_number`, `image`, `created_at`, `updated_at`) VALUES ('1', '[ NO TEXT ]', 'image', '1609035039', 'ALL', 0, 'disney2500.png', '2020-01-31 02:31:35', '2020-01-31 02:31:35')[0m
↳ app/controllers/api/reactions_controller.rb:64
[1m[35m (41.1ms)[0m [1m[31mROLLBACK[0m
↳ app/controllers/api/reactions_controller.rb:64
Completed 500 Internal Server Error in 80ms (ActiveRecord: 43.0ms)
(...)
反应控制器.rb
def create
@reaction = Reaction.new(reaction_params)
option_id = params[:match_option]
tags = params[:tag].split(",")
@option = Option.find_by(id: option_id)
if @reaction.save # <----reactions_controller.rb:64
option_update(@option)
tag_create(tags)
render json: @reaction, status: :ok
else
render json: @reaction.errors, status: :unprocessable_entity
end
end
反应.rb(模型)
class Reaction < ApplicationRecord
mount_uploader :image, ImageUploader
end
解决方案
我建议您使用官方的Cloud Storage Client Library for Ruby
要上传文件,您可以执行以下操作:
# project_id = "Your Google Cloud project ID"
# bucket_name = "Your Google Cloud Storage bucket name"
# local_file_path = "Path to local file to upload"
# storage_file_path = "Path to store the file in Google Cloud Storage"
require "google/cloud/storage"
storage = Google::Cloud::Storage.new project_id: project_id
bucket = storage.bucket bucket_name
file = bucket.create_file local_file_path, storage_file_path
puts "Uploaded #{file.name}"
在文档中,您可以找到更多使用 Ruby 在 GCS 中执行其他任务的示例
推荐阅读
- powershell - 在 Powershell 中使用 TSM 运行自动 Tableau 备份时出错
- multithreading - 调用 TThread 的 Inherited Create 时如何解决访问冲突的问题?
- ios - AppAuth podspec recursive weak_frameworks 未安装为弱
- spss - 如何在SPSS中统计具有相同ID但不同变量的案例
- c++ - Emscripten 崩溃与 mappedGlobals.find(name) != mappedGlobals.end()
- r - 计算包含 NA 的数据的几何平均值
- python - 根据 groupby 条件过滤前 n 行
- postgresql - 如何将触发器与 3 个不同的表一起使用
- vbscript - 从 Outlook 保存具有特定主题的电子邮件的附件
- sparql - 如何检查三元组是否存在?