带有 Rails 3.2.8 的 Paperclip 和 Ajax 问题 [英] Trouble with Paperclip and Ajax with Rails 3.2.8
问题描述
我正在用 rails 3.2.8 编写一个 100% ajax 应用程序
I am writting an application 100% ajax with rails 3.2.8
一切都很顺利,直到我尝试将员工的照片上传到员工管理模块.
Everything was going great until I tried to upload photos of the employees to the employee management module.
这是我的代码的一部分:
This is part of my code:
在控制器:
class EmpleadosController < ApplicationController
respond_to :js
before_filter :require_user
def index
@empleados = Empleado.paginate( page: params[ :page ],
joins: [:user,:contacto],
select: 'empleados.id as id, empleados.user_id, empleados.contratado_el, empleados.despedido_el, empleados.nss, empleados.sueldo_base_semanal, empleados.comentarios, empleados.foto_file_name, empleados.foto_content_type, empleados.foto_file_size, empleados.foto_updated_at, users.username as username, contactos.salutacion_id as salutacion_id, contactos.id as contacto_id, contactos.nombres as nombres, contactos.apellidos as apellidos'
).sorted( params[ :sort ] )
end
def new
@empleado = Empleado.new
end
def create
@empleado = Empleado.new(params[:empleado])
@empleado.sueldo_base_semanal = params[:empleado][:sueldo_base_semanal].gsub(',','').gsub('$','').to_f
if @empleado.save
redirect_to empleados_path
else
render action: 'new'
end
end
...
现在来看视图(我使用的是 HAML):
= form_for( @empleado, remote: true, html: {multipart: true} ) do |f|
= show_me_the_errors @empleado
%table.captura
%tr
%td.etiqueta
= f.label :user_id
%td.campo
= f.select :user_id,
User.usuarios_no_asignados,
{ include_blank: true },
{ tabindex: 1 }
= image_tag 'nuevo_24.png',
style: 'vertical-align: bottom;',
id: 'empleado_nuevo_usuario'
... ( 5 more text fields ) ...
%tr
%td.etiqueta
= f.label :foto
%td.campo
= f.file_field :foto,
accept: 'image/png,image/gif,image/jpeg'
问题是,虽然没有选择要上传的文件,但一切正常,命令 respond_to :js
在 create
与index
和 new
.
The thing is that while there is not selected file for upload, everything works fine, the command respond_to :js
works as it should be in all interactions between create
with index
and new
.
但是,当你选择一张图片时,所有在 create
与 index
和 new
之后的交互都变成了 HTML
完全忽略 respond_to :js
,我的意思是,form for
的行为就像 remote: true
不存在
But, when you select an image, all the interactions after create
with index
and new
become HTML
completely ignoring the respond_to :js
, I mean, the form for
behaves just like if the remote: true
wasn't there
当一切正常时,URL 是 localhost:3000 并且永远不会改变,但是当我选择要上传的图像时,crete
之后的 URL 变为 localhost:3000/empleados
When everything works well, the URL is localhost:3000 and never changes, but when I select an image to upload, the URL after crete
becomes localhost:3000/empleados
有没有人知道这个?在过去的 3 天里,我一直在尝试解决这个问题,但失败了.
Does any one have any clue about this? I have been trying to solve this for the last 3 dyas and failed.
提前谢谢.
推荐答案
好的,经过几天的努力寻找问题,我开始着手解决方案.就是这样:
OK, after several days trying to find the problem I started working on a workaround. So this is it:
1) 我创建了一个用于临时存储的数据库表,ID 字段设置为不带自动增量,并使用普通字段名称:
1) I created a DB Table for temprary storage, with the ID field set without autoincrement, and with the normal field names:
mysql> describe imagens;
+---------------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------------+--------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| imagen_file_name | varchar(500) | YES | | NULL | |
| imagen_content_type | varchar(500) | YES | | NULL | |
| imagen_file_size | int(11) | YES | | NULL | |
| imagen_updated_at | datetime | YES | | NULL | |
| created_at | datetime | NO | | NULL | |
| updated_at | datetime | NO | | NULL | |
| lock_version | int(11) | NO | | 0 | |
+---------------------+--------------+------+-----+---------+-------+
8 rows in set (0.00 sec)
2) 在视图 (_form.html.haml
):
-# this variable will be used as primary key for identifying the image to upload in the database
- ale = Time.now.to_i
3) 在视图 (_form.html.haml
) 处:
我分隔了 file_field
标签
-# FORM for general data input
= form_for( @empleado, remote: true ) do |f|
...
然后,在该表单中,我添加了一个隐藏文件,其中包含变量 ale
和一个非常小的 iframe
then, inside that form I add, a hidden file with the variable ale
and a pretty small iframe
-# I use it in order to find out for wich record to search at the temporary DBTable
= hidden_field_tag :ale, ale
-# this IFRAME will be used to catch the error message returned by rails when uploading the image, it will be invisible
%iframe{src: '#', frameborder:0, height: 0, width: 0, id: 'nulo', name: 'nulo'}
并封装在它自己的 form_for
标签中,但没有任何类型的 submit
或 commit
按钮.
and encapsulated in its own form_for
tag, but without any kind of submit
or commit
button.
= form_for( @imagen, remote: true, html: {multipart: true, target: 'nulo'} ) do |f|
-# used to set the primary key to this value
= hidden_field_tag :ale, ale
= f.file_field :imagen, {style: 'vertical-align: middle;'}
然后一个小的 javascript 来上传图像,当用户选择一个时,它会通过事件触发器提交:
then a little javascript to upload the image when the user choose one, it does the submit by an event trigger:
:javascript
$('#imagen_imagen').change(function(){
$('#new_imagen').submit();
});
4)这是imagen的模型内容(models/imagen.rb):
4) this is the content of the model for imagen (models/imagen.rb):
class Imagen < ActiveRecord::Base
attr_accessible :imagen
has_attached_file :imagen,
styles: { t100: '100x100>', t300: '300x300X', t600: '600x600' },
convert_options: { all: '-strip' },
path: ":rails_root/public/system/:class/:attachment/:id/:style/:filename",
url: "/system/:class/:attachment/:id/:style/:filename",
hash_secret: 'topsecret'
validates_attachment_size :imagen,
less_than: 250.kilobytes,
message: (I18n.t :mensajes)[:paperclip][:grande]
end
5) 这是controllers/imagens_controller.rb 中的代码:
5) this is the code at controllers/imagens_controller.rb :
class ImagensController < ApplicationController
respond_to :js
# by the way, this sline is from authlogic, a great gem to control the access to your site
before_filter :require_user
def create
@imagen = Imagen.new(params[:imagen])
@imagen.id = params[:ale]
@imagen.save
render text: ''
end
end
6) 现在,在 controller/empleados_controller.rb 中的代码是:
6) now, in controller/empleados_controller.rb the code is:
def create
@empleado = Empleado.new(params[:empleado])
if @empleado.save
imagen = Imagen.find(params[:ale].to_i)
if imagen
@empleado.foto = imagen.imagen
@empleado.save
imagen.destroy
end
redirect_to empleados_path
else
@imagen = Imagen.new
render action: 'new'
end
end
7) 词汇表:
图像 = 图像
empleado = 员工
empleados = 员工
ale = aleatorio 的简称,我的意思是随机
ale = short name for aleatorio, I mean, random
foto = 图片或照片
8) 结论:
它有效!!!
9) 待办事项:
缺点是上传图片后,会保存在数据库中,然后可以取消表单或更改页面,这样会留下记录和图片.
The drawback is that after you upload an image, it will be stored at the database, and then you can cancel the form or change page, that will leave the record and picture alive.
一开始,我将在我的管理模块中创建一个链接,该链接会销毁包含临时图像的表中的所有记录,类似于 Imagen.all.each{|x|x.destroy }
At the beginning I will make a link in my admin module that destroys all records from the Table holding the temporary images, with something like Imagen.all.each{|x| x.destroy }
稍后,我将编写一个脚本,在凌晨 2:00 执行该代码.
Later on, I will write a script that at 2:00 a.m. executes that code.
这篇关于带有 Rails 3.2.8 的 Paperclip 和 Ajax 问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!