1

我正在用 rails 3.2.8 编写一个 100% ajax 的应用程序

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

这是我的代码的一部分:

在控制器处:

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之间的所有交互中都应该正常工作。createindexnew

但是,当你选择一个图像时,所有的交互都create完全index忽略newHTMLrespond_to :js我的意思是,form for就像remote: true不存在

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

有人对此有任何线索吗?在过去的 3 天里,我一直在尝试解决这个问题,但失败了。

提前谢谢。

4

1 回答 1

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)

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

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

图像= 图像

empleado = 雇员

empleados = 员工

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

照片= 图片或摄影

8)结论:

有用 !!!

9)待办事项:

缺点是上传图片后,图片会保存在数据库中,然后可以取消表单或更改页面,这样会保留记录和图片。

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

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

于 2012-10-19T14:14:40.920 回答