Saving a csv file with sinatra and datamapper - ruby

Trying to do as the title says using carrierwave but not having much luck as i get the following error:
TypeError - no implicit conversion of CsvFile into String:
here is my post method where it fails:
post '/file' do
file_data = params[:csv_file][:tempfile]
file_name = params[:csv_file][:filename]
file_path = "app/public/csv_files/#{file_name}"
date = Time.now.strftime("%d/%m/%Y %H:%M")
csv_file = CsvFile.new(name: file_name,
path: file_path,
date: date,
file: file_data
)
file = CSV_File_Reader.new(file_path)
erb(:finished)
end
and here is my CsvFile class:
class CsvFile
include DataMapper::Resource
property :id, Serial
property :name, String
property :path, String
property :date, String
mount_uploader :file, File
has n, :images
end
All the params come through as they should but as I'm fairly new to this I'm clearly missing something and googling hasn't worked for me. Any help would be great. Thanks

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]

Ruby Datamapper: retrieving record using param in url path returns null - sometimes

I'm creating a Sinatra App using Datamapper.
With the following route, I'm attempting to print the record for an id. So localhost:9292/api/1 should return results for id=1
inside
get '/api/:id' do
I tried a couple things with varied results:
thing = Thing.get(params[:id])
thing.to_json
end
outputs 'null', but:
id_param = params[:id]
id_param
end
prints 1 as expected, and:
hardcoded_thing = Thing.get(1)
hardcoded_thing.to_json
end
correctly prints the hardcoded db record with id=1. So I must be losing it..
Any ideas?
Thanks!
For reference, here's my model:
class Thing
include DataMapper::Resource
include BCrypt
property :id, Serial, :key => true
property :created_at, DateTime
property :updated_at, DateTime
property :name, String, :length => 50
property :cafe_topic, Text
end
Try this:
get '/api/:id' do |id|
thing = Thing.get(id)
thing.to_json
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.

Ruby not allowing dynamic strings as an argument

I have a class already mapped out and in a database through DataMapper and now I'm trying to make my first resource into the database.
I have a class that handles the form data and file stuff. In that class, I'm creating the first resource with #variables passed in from the params. All other args passed into this resource come from #variables that have values from the form. In this case, #url, the variable in question, is set to a value only a few lines before. Now when I put in the URL:
rec = Post.new(
# more args
:filename_ogg => #url
)
rec.save
This is the killer: Every other line of code in this file is able to access #url, through a global variable ($upload = Upload.new(file)), except for this resource creator. When it comes to saving the resource, it doesn't go through. BUT, when I replace #url with a static string like "RANDOM URL.", it works perfectly. Why?
This had been tested under both MRI 1.9.3 and JRuby 1.6.7.2 (1.9 mode) under Ubuntu 12.04:
# #{user} edited out
class Upload
attr_accessor :file, :filename, :filename_ogg, :status, :title, :desc, :url
def initialize(file)
#file = file
#filename = #file[:filename].gsub(" ", "")
#filename_ogg = "#{#filename}.ogg"
##url = "http://s3.amazonaws.com/#{user}/#{#filename_ogg}"
end
def downandup
# code
end
def convert(file, file_ogg)
# code
end
def upload(file_ogg)
# code
#url = "http://s3.amazonaws.com/#{user}/#{file_ogg}"
# title and desc are accessed through $upload.title/$upload.desc
rec = Post.new(
:title => #title,
:description => #desc,
:author_id => Random.rand(5),
:time_uploaded => Time.now,
:filename_ogg => #url,
:comments_table => Random.rand(10),
)
rec.save
end
end
The file runs through fine, but when it comes for DataMapper to put it in the database, it won't go in, but when replaced with the static string, the data gets stored.

Error happens when I read items in DataMapper

class List
include DataMapper::Resource
property :id, Serial
property :name, String
property :items, String
end
List.auto_migrate!
get '/:id' do
#list = List.all(:id => params[:id])
#items = #list.items
erb :show
end
I get undefined method `items' for #. Any ideas?
You fetch a collection of lists instead of a single list instance, that's why you get the error. I believe you want to do:
#list = List.get(params[:id])

Resources