带有 Rails 3.2.8 的 Paperclip 和 Ajax 问题 [英] Trouble with Paperclip and Ajax with Rails 3.2.8

查看:45
本文介绍了带有 Rails 3.2.8 的 Paperclip 和 Ajax 问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用 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 :jscreateindexnew.

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.

但是,当你选择一张图片时,所有在 createindexnew 之后的交互都变成了 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 标签中,但没有任何类型的 submitcommit 按钮.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆