I'm struggling with CarrierWave.
It worked 1 month ago.
However, it became unwell suddenly, and I can't see any pictures which I've uploaded in browzer!!
Could you tell me the reason ?
index.html.slim
...
h4.h4-title.glyphicon.glyphicon-globe Psara Medical News
- #posts.each do |post|
.container.well
.row
.col-lg-6
.input-group
span.input-group-btn
h5.well.boy
= post.subject
small.pull-right= post.date
- if post.picture.present?
.img-responsive.well alt="Responsive image"
= link_to image_tag post.picture.thumb.url
- if post.video.present?
.img-responsive.well alt="Responsive image"
= link_to #post.video_url.to_s { image_tag(#post.video_url(:screenshot).to_s, id: "video", :alt => "screenshot") }
.img-responsive.well alt="Responsive image"
- if post.body.present?
p.post_text.well
strong= post.body
...
show.html.slim
...
p#notice= notice
.container
.row.well
.col-md-6.well
h4.input-group= #post.subject
h5.input-group= #post.date
- if #post.picture.present?
.col-md-6.well
.input-group= image_tag(#post.picture_url)
- if #post.video.present?
.col-md-6.well
.input-group= link_to #post.video_url.to_s { image_tag(#post.video_url(:screenshot).to_s, id: "video", :alt => "screenshot") }
.col-md-6.well
input-group= #post.body
...
video_uploader.rb
# encoding: utf-8
require 'streamio-ffmpeg'
require 'carrierwave'
class VideoUploader < CarrierWave::Uploader::Base
include Cloudinary::CarrierWave
storage :file
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
def extension_white_list
%w(jpg jpeg gif png mov wmv mp4 flv avi)
end
version :screenshot do
process :screenshot
def full_filename (for_file = model.logo.file)
"screenshot.jpg"
end
end
def screenshot
tmpfile = File.join(File.dirname(current_path), "tmpfile")
File.rename(current_path, tmpfile)
movie = FFMPEG::Movie.new(tmpfile)
movie.screenshot(current_path + ".jpg", preserve_aspect_ratio: :width)
File.rename(current_path + ".jpg", current_path)
File.delete(tmpfile)
end
end
picture_uploader.rb
# encoding: utf-8
require 'carrierwave'
class PictureUploader < CarrierWave::Uploader::Base
include Cloudinary::CarrierWave]
storage :file
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
process :resize_to_limit => [700, 700]
process :convert => 'jpg'
version :thumb do
process :resize_to_limit => [300, 300]
end
def filename
time = Time.now
name = time.strftime('%Y%m%d%H%M%S') + '.jpg'
name.downcase
end
end
Related
I can't figure out why the heck CKEDITOR is not displaying my images...I am using Carrierwave as my uploader to S3, which obviously have been set to all have their own 'uploader.rb' If I upload directly through Carrierwave I have no problems retrieving said image back from S3 to display. BUT if I upload said image through CKEDITOR or attach it inside CKEDITOR it will only display it's source link. This happens in both production and dev localhost.
uploaders/ckeditor_attachement_file_uploader.rb
# encoding: utf-8
require 'carrierwave'
class CkeditorAttachmentFileUploader < CarrierWave::Uploader::Base
include Ckeditor::Backend::CarrierWave
# Include RMagick or ImageScience support:
# include CarrierWave::RMagick
# include CarrierWave::MiniMagick
# include CarrierWave::ImageScience
# Choose what kind of storage to use for this uploader:
if Rails.env.production?
storage :fog
else
storage :file
end
# 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/ckeditor/attachments/#{model.id}"
end
# Provide a default URL as a default if there hasn't been a file uploaded:
# def default_url
# "/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
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
def extension_white_list
Ckeditor.attachment_file_types
end
end
uploaders/ckeditor_picture_uploader.rb
# encoding: utf-8
class CkeditorPictureUploader < CarrierWave::Uploader::Base
include Ckeditor::Backend::CarrierWave
# Include RMagick or ImageScience support:
# include CarrierWave::RMagick
include CarrierWave::MiniMagick
# include CarrierWave::ImageScience
# Choose what kind of storage to use for this uploader:
if Rails.env.production?
storage :fog
else
storage :file
end
# 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/ckeditor/pictures/#{model.id}"
end
# Provide a default URL as a default if there hasn't been a file uploaded:
# def default_url
# "/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
process :extract_dimensions
# Create different versions of your uploaded files:
version :thumb do
process resize_to_fill: [118, 100]
end
version :content do
process resize_to_limit: [800, 800]
end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
def extension_white_list
Ckeditor.image_file_types
end
end
models/picture.rb
class Ckeditor::Picture < Ckeditor::Asset
mount_uploader :data, CkeditorPictureUploader, mount_on: :data_file_name
def url_content
url(:content)
end
end
models/attachement_file.rb
class Ckeditor::AttachmentFile < Ckeditor::Asset
mount_uploader :data, CkeditorAttachmentFileUploader, mount_on: :data_file_name
def url_thumb
#url_thumb ||= Ckeditor::Utils.filethumb(filename)
end
end
I know I am answering my own question but hopefully this will help you. If you are reading this then you obviously have all your storage set up correctly such as S3 (in my case). Your views must require the html_safe method when attempting to display your contents via ckeditor ex.
<div class="col-xs-12">
<h1>Webur Blog</h1>
<h2><%= #blogpost.title %></h2>
<span><p><%= image_tag #blogpost.picture.url if #blogpost.picture? %></p></span>
<p><%= #blogpost.content.html_safe %></p>
<% if is_an_admin %>
<%= link_to "Return to blog", blogposts_path, class: 'btn btn-primary' %>
<%= link_to "Edit Post", edit_blogpost_path, class: 'btn btn-primary' %> |
<%= link_to "Delete Post", blogpost_path(#blogpost),
method: :delete, data: {confirm: "Are you sure?"}, class: 'btn btn-danger' %>
<% else %>
<%= link_to "Return to blog", blogposts_path, class: 'btn btn primary' %>
<% end %>
</div>
Hopefully this helps others. CKeditor does not mention this in their setup guide, and if you are a beginner such as myself you may not catch subtleties like this
I am using Carrierwave to upload picture, after uploaded, I got the error when go to show page:
undefined method `url' for "#ActionDispatch::Http::UploadedFile:0x007f8b6134d610>":String
<%= image_tag #product.picture.url if #product.picture? %>
Here is my code:
_form.html.erb
<div class="picture">
<%= f.file_field :picture %>
</div>
product.rb
class Product < ApplicationRecord
has_many :reviews, dependent: :destroy
mount_uploader :picture, PictureUploader
end
show.html.erb
<p id="notice"><%= notice %></p>
<p>
<strong>Name:</strong>
<%= #product.name %>
</p>
<strong>Picture:</strong>
<%= image_tag #product.picture.url if #product.picture? %>
</p>
<%= link_to 'Edit', edit_product_path(#product) %> |
<%= link_to 'Back', products_path %>
Anyone know how to solve the problem?
Update:
picture_uploader.rb
# encoding: utf-8
class PictureUploader < 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
# Provide a default URL as a default if there hasn't been a file uploaded:
# def default_url
# # 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_white_list
# %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
Here is the version in Gemfile:
gem 'carrierwave', '0.11.2'
gem 'mini_magick', '4.5.1'
gem 'fog', '1.38.0'
I would check first strong params and add :picture attribute if it hasn't been added.
Then I would try to add this in your show views:
show.html.erb
<%= image_tag(#product.picture_url.to_s) %>
instead of this line of code:
<%= image_tag #product.picture.url if #product.picture? %>
In case that you have permissions problem, you can create config file:
config/initializers/carrierwave.rb
and add permissions:
CarrierWave.configure do |config|
config.permissions = 0666
config.directory_permissions = 0777
config.storage = :file
end
in model, you need add
Blockquote
mount_uploader :picture, PictureUploader
Blockquote
I have model Catagory
class Category < ActiveRecord::Base
mount_uploader :image, CategoryImageUploader
end
I need to save the image with the name (id saved category)
class CategoryImageUploader < CarrierWave::Uploader::Base
include CarrierWave::RMagick
storage :file
mounted:
def store_dir
#"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
def store_path(for_file = filename)
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}/#{for_file}"
end
version :small do
process resize_to_fit: [48, 48]
def filename(uploaded_file = file)
if uploaded_file.present?
"small_#{model.id}.#{uploaded_file.extension}"
end
end
end
version :big do
process resize_to_fit: [200, 200]
def filename(uploaded_file = file)
if uploaded_file.present?
"big_#{model.id}.#{uploaded_file.extension}"
end
end
end
def filename(uploaded_file = file)
if uploaded_file.present?
"#{model.id}.#{uploaded_file.extension}"
end
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
I'm use https://coderwall.com/p/mulldw/custom-file-names-with-carrierwave-and-amazon-s3 to save image like this 3.png 4.png
version :small and version :big aslo save (like big_3.png small_3.png )
but
**Category.last.image_url => "/uploads/category/image/10/10.png"
Category.last.image_url(:small) = > "/uploads/category/image/10/10.png"
Category.last.image_url(:big) = > "/uploads/category/image/10/10.png"**
All links lead to one image 10.png
I need
**Category.last.image_url => "/uploads/category/image/10/10.png"
Category.last.image_url(:small) = > "/uploads/category/image/10/small_10.png"
Category.last.image_url(:big) = > "/uploads/category/image/10/big_10.png"**
I hava a uploader for pdf documents. After, uploader have a method to create an thumb image of pdf file.
This is the uploader:
require 'carrierwave/processing/mime_types'
class DocumentUploader < CarrierWave::Uploader::Base
include CarrierWave::RMagick
include Sprockets::Helpers::RailsHelper
include Sprockets::Helpers::IsolatedHelper
include CarrierWave::MimeTypes
IMAGE_EXTENSIONS = %w(png)
DOCUMENT_EXTENSIONS = %w(pdf)
storage :fog
def store_dir
"documents/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
def extension_white_list
IMAGE_EXTENSIONS + DOCUMENT_EXTENSIONS
end
# create a new "process_extensions" method. It is like "process", except
# it takes an array of extensions as the first parameter, and registers
# a trampoline method which checks the extension before invocation
def self.process_extensions(*args)
extensions = args.shift
args.each do |arg|
if arg.is_a?(Hash)
arg.each do |method, args|
processors.push([:process_trampoline, [extensions, method, args]])
end
else
processors.push([:process_trampoline, [extensions, arg, []]])
end
end
end
# our trampoline method which only performs processing if the extension matches
def process_trampoline(extensions, method, args)
extension = File.extname(original_filename).downcase
extension = extension[1..-1] if extension[0,1] == '.'
self.send(method, *args) if extensions.include?(extension)
end
def cover
manipulate! do |frame, index|
frame if index.zero?
end
end
version :thumb do
process :cover
#process :resize_to_limit => [110, 60]
process_extensions IMAGE_EXTENSIONS, :resize_to_fit => [110, 60]
process :convert => 'png'
end
process :set_content_type
process :save_content_type_and_size_in_model
def save_content_type_and_size_in_model
model.content_type = file.content_type if file.content_type
model.file_size = file.size
end
end
However when I see the files (both, pdf and thumb image) inside of amazon s3, the extension for thumbnail is .pdf instead of .png:
How can I change the pdf extension to .png and content_type of thumb image?
This works for me to set the extension:
version :thumb do
process :resize_to_fit => [150, 150]
process :convert => 'png'
def full_filename (for_file = model.source.file)
super.chomp(File.extname(super)) + '.png'
end
end
Essentially, the photo_url(:thumb) displays the intended thumb url even though the file doesn't physically exist.
# encoding: utf-8
class WinePhotoUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
storage :file
# So the :thumb will be stored in "public/assets/wines/thumb/2008-meritage-750mL.jpg" for example.
def store_dir
"assets/wines/#{version_name}"
end
def cache_dir
Rails.root.join 'tmp/uploads'
end
CarrierWave::SanitizedFile.sanitize_regexp = /[^[:word:]\.\-\+]/
# If no version name is present (original), just provide the thumb path
# This method is never called!!! Why not?
def default_url
ActionController::Base.helpers.asset_path("pages/wines/#{version_name || :thumb}/default.png")
end
# To save disk space, make sure the original image is no larger than the croppable + a few pixels
process :resize_to_fit => [2000, 2000]
version :croppable, :if => :not_cropping? do
process :common
process :resize_and_pad => [1200, 1200, :white]
process :convert => "jpg"
# Override the default naming convention...I store in folders,
# so I don't want the version prepended to the file name.
def full_filename(for_file = model.photo.file)
the_filename
end
end
version :show, :if => :not_cropping? do
process :resize_to_show
process :convert => "jpg"
def full_filename(for_file = model.photo.file)
the_filename
end
end
version :thumb, :from_version => :croppable, :if => :viewing_or_cropping? do
process :custom_thumbnail => [200, 200]
def full_filename(for_file = model.photo.file)
the_filename
end
end
def common(q=100, s='1.2x1+0.75+0.05')
manipulate! do |img|
img.combine_options do |i|
i.quality q
i.antialias
i.background :white
i.flatten
i.density 72
i.profile "#{Rails.root}/lib/color_profiles/sRGB_v4_ICC_preference_displayclass.icc"
i.strip
end
img = yield(img) if block_given?
img.combine_options do |i|
i.unsharp s
end
img
end
end
def resize_to_show
common do |img|
img.combine_options do |i|
i.trim
i.thumbnail 110
i.background :white
i.gravity :center
i.extent 170
end
img
end
end
def custom_thumbnail(width, height)
manipulate! do |img|
img.combine_options do |i|
i.distort :srt, "#{model.crop_x},#{model.crop_y} 1 -30 600,600"
i.repage.+
i.gravity :center
i.crop "#{model.crop_w}x#{model.crop_h}+0+0"
i.repage.+
i.thumbnail "#{width}x#{height}"
i.unsharp '1.2x1+0.75+0.05'
end
img
end
end
def not_cropping? picture
!model.cropping?
end
# For some stupid reason, if I only check for 'model.cropping?' and
# it returns false, the photo_url(:thumb) will always show the default_url
# and never show the actual url! This is terrible logic. The version declarations
# above should only affect the generation of thumbnails, not whether the call
# to photo_url(:thumb) works.
def viewing_or_cropping? picture
model.cropping? or model.changes.merge(model.previous_changes).empty?
end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
def extension_white_list
%w(jpg jpeg gif png tif tiff)
end
# Only modify the version names, not the original uploaded file name
def filename
"#{ model.get_permalink(:normalized => true) }#{ File.extname original_filename }" if original_filename
end
# The filename should be the wine's permalink name (ex., 2008-merlot-reserve-750mL.jpg)
def the_filename
"#{ model.get_permalink(:normalized => true) }.jpg"
end
# Remove this when https://github.com/carrierwaveuploader/carrierwave/issues/1164 is solved.
def recreate_versions!(*versions)
if versions.any?
from_versions = versions.group_by { |v| self.class.versions[v][:options][:from_version] }
from_versions.each do |from, versions|
next if from.nil?
file = CarrierWave::SanitizedFile.new(self.versions[from.to_sym].file)
store_versions!(file, versions)
end
else
super(*versions)
end
end
end
So a call to #wine.photo_url(:thumb) produces
http://dev.mydomain.com/assets/wines/thumb/2006-cabernet-sauvignon-750mL.jpg
when it should be producing
http://dev.mydomain.com/assets/pages/wines/thumb/default.png
because the file doesn't exist.
My best guess is that Carrierwave generates the file names based on the existence of the model's attribute in the database and not whether or not the specific version of the file exists. Not what I was expecting from default_url but it still makes sense in its limited way.