Sube una foto de iPhone al servidor Rails con adjunte_fu
-
27-10-2019 - |
Pregunta
Creo que he podido enviar una foto desde el iPhone a los rieles usando el formato multipart, pero una vez que la foto llega al servidor Rails, no puedo entender cómo guardarla correctamente. Creo que el archivo aparece en los parámetros en el servidor Rails como "archivo de usuario" al final de los parámetros a continuación cuando se llama a iPhone_photo_to_website:
Parameters: {"action"=>"iphone_photo_to_website","id"=>"8A39FA8F_1ADD_52AB_8387_E1C5CFC4AB2D", "controller"=>"users", "userfile"=>#<File:/tmp/RackMultipart30053-0>}
Envío la foto desde el iPhone usando el siguiente código Objective-C de la siguiente pregunta:
¿Cómo puedo subir una foto a un servidor con el iPhone?
NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"logo1" ofType:@"png"];
NSData *imageData = [NSData dataWithContentsOfFile:imagePath];
NSString *urlString = [NSString stringWithFormat:@"%@/users/iphone_photo_to_website/%@",
serverString, UID];
NSMutableURLRequest *imageRequest = [[NSMutableURLRequest alloc] init] ;
[imageRequest setURL:[NSURL URLWithString:urlString]];
[imageRequest setHTTPMethod:@"POST"];
NSString *boundary = [NSString stringWithString:@"---------------------------14737809831466499882746641449"];
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];
[imageRequest setValue:contentType forHTTPHeaderField: @"Content-Type"];
NSMutableData *body = [NSMutableData dataWithCapacity:[imageData length] + 512];
[body appendData:[[NSString stringWithFormat:@"--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:@"Content-Disposition: form-data; name=\"userfile\"; filename=\"logo1.png\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:@"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[NSData dataWithData:imageData]];
[body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[imageRequest setHTTPBody:body];
theConnection = [[NSURLConnection alloc] initWithRequest:imageRequest
delegate:self];
En el servidor Rails, la migración de fotos en DB/migrate parece:
class CreatePhotos < ActiveRecord::Migration
def self.up
create_table :photos do |t|
t.column :user_id, :integer
t.column :title, :string
t.column :body, :text
t.column :created_at, :datetime
# the following are for attachment_fu
t.column :photo, :binary
t.column :content_type, :string
t.column :filename, :string
t.column :size, :integer
t.column :parent_id, :integer
t.column :thumbnail, :string
t.column :width, :integer
t.column :height, :integer
end
end
def self.down
drop_table :photos
end
end
En el servidor Rails tengo una aplicación de modelo de foto/modelos/photo.rb con el siguiente código:
class Photo < ActiveRecord::Base
has_attachment :storage => :file_system,
:resize_to => '640x480',
:thumbnails => { :thumb => '160x120', :tiny => '50>' },
:max_size => 5.megabytes,
:content_type => :image,
:processor => 'Rmagick'
validates_as_attachment
belongs_to :user
end
Y el controlador Rails tiene el siguiente código:
def iphone_photo_to_website
@udid = params[:id]
@userfile = params[:userfile]
@photo_params = { :user_id => @user.id,
:photo => @userfile,
:content_type => 'image',
:filename => @userfile.original_path,
:uploaded_data => @userfile
}
image = Photo.new(@photo_params)
image.save
end
Cuando se ejecuta "Image.save", devuelve "falso". ¿Alguien sabe cómo puedo encontrar qué error está causando la imagen. ¿O alguien sabe cómo puedo guardar la foto correctamente en la base de datos?
Solución
Finalmente pude guardar la imagen en la base de datos utilizando el siguiente código:
@userfile = params[:userfile]
image = Photo.new(:uploaded_data => params[:userfile])
image.user_id = @user.id
image.photo = @userfile
image.width = 105
image.height = 104
basename = File.basename(image.filename).gsub(/[^\w._-]/, '')
image.content_type = "image/" + basename.split("\.")[1]
image.save
Cuando la imagen se crea como una foto. Nuevo usando el campo uploaded_data, la imagen.FileName se establece.
También tuve que eliminar la siguiente línea del código Objective-C en el iPhone para que las cosas funcionen.
[body appendData:[[NSString stringWithString:@"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];