Télécharger une photo de l'iPhone au serveur Rails avec attachment_fu
-
27-10-2019 - |
Question
Je pense que je suis en mesure d'envoyer une photo de l'iPhone à Rails en utilisant le format multipart, mais une fois la photo obtient au serveur Rails, je ne peux pas comprendre comment enregistrer correctement. Je pense que le fichier apparaît dans les params sur le serveur Rails comme « userfile » à la fin des paramètres ci-dessous lorsque iphone_photo_to_website est appelé:
Parameters: {"action"=>"iphone_photo_to_website","id"=>"8A39FA8F_1ADD_52AB_8387_E1C5CFC4AB2D", "controller"=>"users", "userfile"=>#<File:/tmp/RackMultipart30053-0>}
J'envoyer la photo de l'iPhone en utilisant le code suivant Objective-C de la question suivante de SO:
Comment puis-je télécharger une photo à un serveur avec l'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];
Sur le serveur Rails la migration photo dans les regards db / migrate comme:
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
Sur le serveur Rails j'ai une application modèle Photo / modèles / photo.rb avec le code suivant:
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
Et les Rails contrôleur a le code suivant:
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
Lorsque "exécute de Image.Save", il retourne "false". Est-ce que quelqu'un sait comment je peux trouver ce que l'erreur est à l'origine image.save de fausse déclaration? Ou que quelqu'un sait comment je peux enregistrer la photo correctement dans la base de données?
La solution
J'a finalement pu enregistrer l'image dans la base de données en utilisant le code suivant:
@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
Lorsque l'image est créée en tant que Photo.new en utilisant le champ uploaded_data, le image.filename se prépare.
Je devais aussi retirer la ligne suivante à partir du code Objective-C sur l'iPhone pour faire avancer les choses au travail.
[body appendData:[[NSString stringWithString:@"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];