Image upload in ruby with sinatra and datamapper and Carrierwave? - ruby

I want to upload a single image with Carrierwave, the thing is, it is uploading the file and saving it into the directory uploads, in this folder it creates another folder called tmp, and in the tmp folder it creates another folder which includes the image.
The thing is it doesn't seem to stop it is uploading and uploading and uploading all the time even if the image is fully uploaded into that folder and I can open this image already with feh(or anyother image viewer).
This is what my controller looks like.
get "/new" do
protect!
erb :new
end
post "/new" do
protect!
#user = User.get(session[:user_id])
image = #user.image.new(
:description => params[:description],
:image => params[:image]
)
# image.save
"NEVER REACHED!"
end
(The text "NEVER REACHED!" won't be displayed at all and I don't know why...)
This is my model:
class ImageUploader < CarrierWave::Uploader::Base
def extensions_white_list
%w(jpg jpeg gif png)
end
storage :file
end
class Image
include DataMapper::Resource
property :id, Serial
property :description, Text
property :image, String, :auto_validation => false
mount_uploader :image, ImageUploader
end
class User
include DataMapper::Resource
property :id, Serial
has n, :post
end
So as already mentioned the Text "NEVER REACHED" is never reached. Any Ideas why?
Besides I always get the warning:
Defining property for an uploader is deprecated at /usr/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
And I do not know why...
UPDATE: It is somehow working now as long as I do not uncomment image.save in the main controller, but I actually need to uncomment this, any Ideas how to fix this?

Remove property :image line in your Image model as:
class Image
include DataMapper::Resource
property :id, Serial
property :description, Text
mount_uploader :image, ImageUploader
end
mount_uploader by itself defines the :image as String type.
Try to run your application after this and let me know if the condition remains the same. :)

Related

How to fix a "value too long for type character varying(255)" error

I'm trying to save a file so that I can upload it to stripe using CarrierWave, but I'm getting the error:
ERROR: value too long for type character varying(255)
and don't understand why as I followed the CarrierWave usage guide on GitHub.
This is my application:
class SplitterStripeServer < Sinatra::Base
CarrierWave.configure do |config|
config.root = File.dirname(__FILE__) + "/public"
end
post "/" do
img = Image.new
img.file = params[:file] #carrierwave will upload the file automatically
img.save!
redirect to("/")
end
get "/upload" do
erb :upload
end
get "/" do
#image = Image.find(1)
erb :index
end
end
This is the uploader:
class ImagesUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
storage :file
end
This is the model:
class Image
include DataMapper::Resource
property :id, Serial
mount_uploader :file, ImagesUploader
end
I feel like I'm missing something simple.
You need to decrease a length of a file name. Override filename method and cut a file's basename e.g. to 250 characters.
class ImagesUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
storage :file
def filename
"#{file.basename[0..250]}.#{file.extension}" if original_filename.present?
end
end
check if you have additional installed gems
I had was installed gem validates_lengths_from_database and this gem doesn't understand how to work with carrierwave. I am just turn off it in model validates_lengths_from_database except: %i[file]

Mapping through Paperclip image styles

I have an Album that uses the Paperclip gem to store artwork image uploads. The artwork attribute has a list of styles of different image sizes: thumb, medium, and large.
class Album < ActiveRecord::Base
has_attached_file :artwork, styles: { thumb: "50x50#", medium: "160x160#", large: "300x300#" }
...
end
In my active model serializer I want to create an array-based images attribute that stores the urls of each of these sizes. Traditionally I would do something like this:
class AlbumSerializer < ActiveModel::Serializer
attributes :id, :name, :images
def images
[object.artwork.url(:thumb), object.artwork.url(:medium), object.artwork.url(:large)]
end
end
Is there a way I could just map through each style instead of having to write the same call to the artwork url? I tried getting the hash of styles as so but got it returned nothing:
album.artwork.styles
=> {}
Any idea on getting this to work?
Not sure about the paperclip part (the "styles array"), but you could do:
def images
[:thumb, :medium, :large].map { |style| object.artwork.url(style) }
end

Where does CarrierWave stores uploads

Please help me understand how does CarrierWave works.
I'm using minimal Sinatra/DataMapper app with following contents:
class VideoUploader < CarrierWave::Uploader::Base
storage :file
end
class Video
include DataMapper::Resource
property :id, Serial
property :name, String
property :desc, Text
mount_uploader :file, VideoUploader
end
get '/' do
slim :form
end
post '/' do
video = Video.new
video.name = params[:name]
video.desc = params[:desc]
video.file = params[:file]
video.save
redirect '/'
end
As I understood mount_uploader :file, VideoUploader string in Video definition adds .video method to Video instance, and I can store uploads assigning params[:file] to it. When I'm trying to send form from browser, the request successfully creates record in DB table, but I can't find any signs of file existence either in DB and public_directory. What I'm doing wrong?
You probably should define the store_dir method inside the VideoUploader class:
class VideoUploader < CarrierWave::Uploader::Base
storage :file
# 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
....
end

Datamapper + Carrierwave store method not being called, only cache

I have a really simple sinatra app which uses datamapper and carrierwave.
I've reduced the uploader to its minimum:
class PhotoUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
storage :file
end
And have one simple model that uses it:
class Photo
include DataMapper::Resource
property :id, Serial
property :caption, String
property :position, Integer
property :created_at, DateTime
property :updated_at, DateTime
mount_uploader :source, PhotoUploader
belongs_to :album
end
It happens that when I use it:
post '/admin/album/:id/photo/create' do
album = Album.get(params[:id])
photo = Photo.create(params[:photo])
album.photos << photo
album.save!
redirect '/admin/album'
end
photo is being created normally on the database and the file is being uploaded normally to the cache directory but not being moved to the final storage destination.
I've got into the carrierwave code and could verify that the cache! method is being called but not the store! method.
I've tried to use the uploader without any association to the object:
get '/lorem' do
f = File.open('test.png')
u = PhotoUploader.new
u.store!(f)
"ok"
end
Everything works as expected in this case.
==================== UPDATE ====================
I belive I've found the source of the problem. While running debugger I got to this:
gems/dm-core-1.2.0/lib/dm-core/query.rb:1014
conditions.each do |condition|
(rdb:1)
gems/carrierwave-0.6.2/lib/carrierwave/sanitized_file.rb:290
def sanitize(name)
(rdb:4)
gems/carrierwave-0.6.2/lib/carrierwave/sanitized_file.rb:299
def split_extension(filename)
(rdb:4)
gems/carrierwave-0.6.2/lib/carrierwave/sanitized_file.rb:29
self.file = file
(rdb:4)
gems/carrierwave-0.6.2/lib/carrierwave/sanitized_file.rb:269
if file.is_a?(Hash)
(rdb:4)
gems/carrierwave-0.6.2/lib/carrierwave/sanitized_file.rb:274
#file = file
(rdb:4) pp file
"/Users/jvalente/Projects/dummy/public/uploads/{:filename=>\"Screen Shot 2013-01-24 at 4.57.15 PM.png\", :type=>\"image/png\", :name=>\"photo[source]\", :tempfile=>#<File:/var/folders/jp/wm1gxk8558d36rh9vzkmx4jw0000gn/T/RackMultipart20130128-27245-105ybbf>, :head=>\"Content-Disposition: form-data; name=\\\"photo[source]\\\"; filename=\\\"Screen Shot 2013-01-24 at 4.57.15 PM.png\\\"\\r\\nContent-Type: image/png\\r\\n\"}"
This clearly is wrong since it will fail the file.is_a?(Hash) condition and get into:
#file = file
#original_filename = nil
#content_type = nil
Still, I can't understand why this happens.

cant use has_secure_password, password_digest error

Good evening. I have a problem. i am using has_secure_password
and cause of this i have an error undefined methodpassword_digest=' for #`,
but i dont have this method!! Please help, dont know what to do. I read how to fix this problem but it didnt help me(
Here is my User model. Please help if you can.
class User < ActiveRecord::Base
attr_accessible :email, :password, :password_confirmation
has_secure_password
validates_presence_of :password, :on => :create
before_create { generate_token(:auth_token) }
def send_password_reset
generate_token(:password_reset_token)
self.password_reset_sent_at = Time.zone.now
save!
UserMailer.password_reset(self).deliver
end
def generate_token(column)
begin
self[column] = SecureRandom.urlsafe_base64
end while User.exists?(column => self[column])
end
end
You may have forgotten to make sure your migration backing the user model has a column for password_digest. Make sure the column exists and that it's a string. If it doesn't, create a migration to add the column.
Models having has_secure_password store password in password_digest column instead of password column.
In fact password column is not needed.
> u=User.create!(email: 'user#gmail.com', password: '12345678')
> u
#<User:0x007fc794be9278> {
:id => 1,
:email => "user#gmail.com",
:password_digest => "$2a$10$S82GVFR..yO9jihgIoeMj.7dNMWtbCUZpWDKvH0tyMs1SYlfdefmW"
}
I had the same problem, I was following http://www.railstutorial.org/book/modeling_users
and my app/Controllers/users_controllers.rb didn't have a method to create the attribute, I also used git to share the working code between portable laptop for the train and larger home, this created the migration file but didnt apply it, my working user controller is below.
class UsersController < ApplicationController
def new
attr_accessor :name, :email, :password
def initialize(attributes = {})
#name = attributes[:name]
#email = attributes[:email]
#password = attributes[:password]
end
def formatted_email
"#{#name} <#{#email}>"
end
end
Hey I'm following RoR too and come into the same problem. The trick here is your bundle exec rake db:migrate fails and therefore the password_digest column hasn't been added into the database. My console complains that database for User already exists. I delete the db/development.sqlite3 manully with "SQLite Browser". After running bundle exec rake db:migrate, every test passes

Resources