Paperclip和Ajax与Rails 3.2.8的问题

时间:2012-10-18 12:53:49

标签: ruby-on-rails-3 paperclip

我正在使用rails 3.2.8编写应用程序100%ajax

在我尝试将员工照片上传到员工管理模块之前,一切都很顺利。

这是我的代码的一部分:

在Controller:

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 :jscreateindex和{{new之间的所有互动中都应有效。 1}}。

但是,当您选择图片时,create indexnew之后的所有互动都会HTML完全忽略respond_to :js,我的意思是, form for的行为就像remote: true不存在

一样

当一切正常时,URL为localhost:3000并且永远不会更改,但是当我选择要上传的图像时,crete之后的URL将变为localhost:3000 / empleados

有人对此有任何线索吗?我一直试图在最后3个dyas中解决这个问题并且失败了。

提前做出来。

1 个答案:

答案 0 :(得分:3)

好的,经过几天试图找到问题,我开始研究解决方法。所以就是这样:

1)我创建了一个用于临时存储的数据库表,其中ID字段设置为不带自动增量,并且具有正常的字段名称:

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)
视图(_form.html.haml)上的

2)

-# this variable will be used as primary key for identifying the image to upload in the database
- ale = Time.now.to_i 
视图(_form.html.haml)上的

3)

我将file_field标记

分开了
-# FORM for general data input
= form_for( @empleado, remote: true ) do |f|
  ...

然后,在我添加的表单中,隐藏文件包含变量ale和非常小的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按钮。

= 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,它通过事件触发器进行提交:

:javascript
  $('#imagen_imagen').change(function(){
    $('#new_imagen').submit();
  });

4)这是 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的代码:

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中,代码为:

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)词汇表:

imagen = image

empleado =员工

empleados =员工

ale = aleatorio的简称,我的意思是,随机

foto = picture o photograpy

8)结论:

有效!!!

9)待办事项:

缺点是上传图像后,它将存储在数据库中,然后您可以取消表单或更改页面,这将使记录和图片保持活动状态。

一开始我会在我的管理模块中创建一个链接,该链接会破坏表中包含临时图像的所有记录,例如Imagen.all.each{|x| x.destroy }

稍后,我将编写一个脚本,凌晨2点执行该代码。