Upload file semplice


#1

Ciao a tutti,
ho creato una form per fare l’upload di un file:

<% form_for(@image, :multipart => true) do |f| %>
<%= f.file_field :foto %>
<%= f.text_field :titolo %>
<% end %>

Nel database mysql ho creato un campo di tipo blob e nel controller ho
messo:

@image = Image.new(params[:image])
@image.save

Il browser sembra caricare la foto ma poi quando vado sulla vista trovo
solo il titolo e nel campo blob del database il percorso del file del
mio pc…
Dove sbaglio?


#2

probabilmente non hai specificato di salvare i file nel db,
sinceramente nn so che vantaggi puoi avere, io di solito li salvo come
file.


#3

Andrea C. wrote:

probabilmente non hai specificato di salvare i file nel db,
sinceramente nn so che vantaggi puoi avere, io di solito li salvo come
file.

Scusa la mia ingenuita’… io pensavo che con @image.save si salvassero
tutti!
Ma allora cosa devo scrivere per salvare il file nel db?


#4

non mi ricordo, dovresti configurarlo, sinceramente mi sa che non ho
nemmeno mai provato, ma qual’ è il problema, nn puoi salvarli su file?

Q


#5

Potrei ma come si fa?
Io vorrei che la form fosse semplice…


#6

Sul submit hai ragione, non ho copiato bene…
Si, il metodo e’ images_controller.rb
Il database ha diversi campi e un campo foto di tipo blob.
Nel file database.yml ho messo:
adapter: mysql
encoding: utf8
database: nome
username: user
password: pass
host: host


#7

Marco Pi wrote:

Ciao a tutti,
ho creato una form per fare l’upload di un file:

<% form_for(@image, :multipart => true) do |f| %>
<%= f.file_field :foto %>
<%= f.text_field :titolo %>
<% end %>

Nel database mysql ho creato un campo di tipo blob e nel controller ho
messo:

@image = Image.new(params[:image])
@image.save

Il browser sembra caricare la foto ma poi quando vado sulla vista trovo
solo il titolo e nel campo blob del database il percorso del file del
mio pc…
Dove sbaglio?

Ciao…
comunque nel form manca il submit che deve esser incluso tra il
form_for-end
<% form_for(@image, :multipart => true) do |f| %>
<%= f.file_field :foto %>
<%= f.text_field :titolo %>

<%= f.submit “Invia il file al db” %>
<% end %>

Che metodo è del controller penso Images_controller.rb:

@image = Image.new(params[:image])
@image.save

Inserisci la struttura del database.yml

Ciao
Daniel


#8

Cecchin Daniel wrote:

Marco Pi wrote:

Sul submit hai ragione, non ho copiato bene…
Si, il metodo e’ images_controller.rb
Il database ha diversi campi e un campo foto di tipo blob.
Nel file database.yml ho messo:
adapter: mysql
encoding: utf8
database: nome
username: user
password: pass
host: host

ti manca il soket che è il percorso del tuo mysql e forse host deve aver
valore localhost se stai operando in locale… altrimenti non saprei.
Ma se ti inserisce il titolo mmmh… non saprei fai un drop dei
parametri e poi riprova a verificare se te lo inserisce…

Capitoooooo scusami non avevo capito bene il problema…
fammi vedere la tua views.rhtml


#9

Il titolo lo inserisce… non capisco.
A me andrebbe bene anche salvare ll’immagine in una cartella e mettere
nel db l’url ma ho porvato in mille modi.
Il problema e’ che sul mio pc funziona, sul server sul quale ho
pubblicato non va…


#10

Marco Pi wrote:

Sul submit hai ragione, non ho copiato bene…
Si, il metodo e’ images_controller.rb
Il database ha diversi campi e un campo foto di tipo blob.
Nel file database.yml ho messo:
adapter: mysql
encoding: utf8
database: nome
username: user
password: pass
host: host

ti manca il soket che è il percorso del tuo mysql e forse host deve aver
valore localhost se stai operando in locale… altrimenti non saprei.
Ma se ti inserisce il titolo mmmh… non saprei fai un drop dei
parametri e poi riprova a verificare se te lo inserisce…


#11

Ho usato questo sistema che sul mio pc funziona:
http://www.tutorialspoint.com/ruby-on-rails/rails-file-uploading.htm


#12

Marco Pi wrote:

la vista e’ nel primo post

Penso che il problema sia del percorso della directory
Prova a controllare il file nel sever e verificare se c’è il file
salvato!
class DataFile < ActiveRecord::Base
def self.save(upload)
name = upload[‘datafile’].original_filename
directory = “public/data” ####################################<
# create the file path
path = File.join(directory, name)
# write the file
File.open(path, “wb”) { |f| f.write(upload[‘datafile’].read) }
end
end


#13

Marco Pi wrote:

la vista e’ nel primo post

Io farei una cosa di questo genere… partendo da uno Shaffold
modificherei il model e il controller adattando il file… sorgente che
hai quì…
Altrimenti penso che quel codice ti farà , ad un’occhiatta veloce, solo
l’aggiunta del file e non la visualizzazione… mancano dei controller…
per me… ma non sono un espertissimo è da 6 mesi che utilizzo Ruby on
Rails


#14

la vista e’ nel primo post


#15

Ho sentito parlar molto bene di attachment_fu, un plugin che fa al caso
tuo.

Ciao Michele.


#16

attachmenth_fu non si usa praticamente pìù, usa paper clip


#17

Dopo aver abbandonato l’idea di caricare le immagini in una cartella
sono tornato all’inserimento nel database e ho pensato di postare tutto
il codice (da manuale di rails) che non mi funziona ma che finalmente mi
indica un errore:
Mysql::Error: #22001Data too long for column ‘foto’ at row 1: INSERT
INTO images (image_url, content_type, ecc.).
Certo che e’ strano che un campo blob non riesca a contenere una foto da
pochi k.

Il model:

class Image < ActiveRecord::Base

validates_format_of :content_type,
:with => /^image/,
:message => “e’ possibile caricare solo immagini”

def image=(image_field)
self.image_url = base_part_of(image_field.original_filename)
self.content_type = image_field.content_type.chomp
self.foto = image_field.read
end

def base_part_of(file_name)
image_url = File.basename(file_name)
image_url.gsub(/[^\w._-]/, ‘’)
end

end

La vista (get.html.erb):

<%=form_tag({:action => 'save'}, :multipart => true)%>
Foto
<%=file_field("image","image")%>
Titolo
<%=text_field :image, :titolo %>
Descrizione
<%=text_area :image, :descrizione %>
<%= submit_tag "Salva" %>

Il controller:

class UploadController < ApplicationController

before_filter :authorize

def get
@image = Image.new
end

def save
@image = Image.new(params[:image])
if @image.save
redirect_to(:action=> “index”)
else
render :action => “get”
end
end

end

La tabella del database:

images (

id int(11) NOT NULL auto_increment,

titolo varchar(100) NOT NULL,

descrizione text,

image_url varchar(200) NOT NULL,

foto blob,

content_type varchar(100) default NULL,

PRIMARY KEY (id)
);


#18

Provo ad aiutarti senza l’utilizzo di nessun plugin, che poi con il
passare del tempo non funziona più. Le operazioni da fare sono 3: nel
controller, nella vista e nel model.

Nel controller definisci:

def saveimage
@book=Book.find(params[:id])
if @book.update_attributes(params[:book])
if @book.save
flash[:notice]=‘Immagine caricata.’
redirect_to :back
end
else
flash[:notice]=‘Errore: Immagine non caricata.’
redirect_to :back
end

In una vista che sceglierai tu, generalmente è quella da cui effettui le
modifiche alla riga del db, scrivi:


Caricare Immagine:

Come vedi, nell’ultimo snippet, la vista fa riferimento alla tabella
book e all’item book, sembrerebbe quindi che nella tabella book esista
un item book di tipo “blob”. Questo però non è vero perché l’item book è
virtuale e serve esclusivamente per richiamare il Model del “book”.
Questo vuol dire che nel model del book dovrai inserire:

class Book < ActiveRecord::Base

def book=(book_field)
self.cover=book_field.read
end

il codice scritto ti dice che nella tabella book l’item di tipo “blob” è
cover!

Spero di esserti stato d’aiuto

Luigi


#19

Dalla mia esperienza ti posso confermare la bontà dei consigli di Luigi,
io avevo fatto qualcosa “da me” ma su filesystem. Ti consiglierei di
utilizzare questo tipo di storage che è nato per questo scopo mentre il
database per uno molto più generico quindi le prestazioni secondo me ne
risentono, anche se non ho mai fatto test in prima persona.

Se dovessi provare il filesystem ricordati di leggere a “trance” il file
per evitare di saturare il processo (specialmente se usi un host web):
File.open(path, “wb”) { |f| f.write(upload[‘datafile’].read(4096)) }

Io ti consiglio comunque di usare un plugin per evitare inutili noie che
altri hanno già affrontato, magari più generici ma probabilmente più
accurati, questo è paperclip su database (se proprio non vuoi usare il
filesystem):
http://patshaughnessy.net/2009/2/19/database-storage-for-paperclip

Anche attachment_fu è un ottimo plugin, anche se con paperclip ci fai di
tutto e se non è richiesta complessità rimane più semplice e flessibile.
Io li ho usati entrambi, attachment_fu mi ha dato qualche problema di
memoria quando utilizzavo rmagick (mentre paperclip non usa questa
gemma, gestisce direttamente imagemagick) invece usato con imagescience
non ho riscontrato problemi (di default usa questo).
In definitiva, io starei su paperclip.


#20

sfrutto il thread, plugin che simulino un comportamento in stile svn ?
devo versionare degli allegati…