如何在文件上传时使用Rails的update_attributes?

时间:2011-02-15 17:17:16

标签: ruby-on-rails ruby model-view-controller

我对产品控制器的更新方法定义如下:

def update
  @product = Product.find(params[:id])

  if params[:product][:image_path]
    # Check if this product already has an image
    File.delete(@product.full_image_path) if File.exist?(@product.full_image_path)
    # Upload the new image
    uploaded_img = params[:product][:image]
    @product.image_path = Time.now.to_i.to_s + File.extname(uploaded_img.original_filename)
    File.open(@product.full_image_path, 'w') do |file|
      file.write(uploaded_img.read)
    end
  end

  @product.name = params[:product][:name]
  @product.description = params[:product][:description]

  respond_to do |format|
    if @product.errors.count == 0
      format.html { redirect_to products_path, :notice => t(:product_updated) }
      format.xml { head :ok }
    else
      format.html { render :action => "edit" }
      format.xml { render :xml => @product.errors, :status => :unprocessable_entity }
    end
  end
end

如果已经存在,则只删除旧图像,并上传新图像。它还会更新产品属性

如何使用@product.update_attributes(params[:product])来避免更新名称和描述属性,就像我在这里所做的那样?

如果我@product.update_attributes(params[:product])我收到错误,因为params散列包含一个名为“image”的值,该值不是该对象的属性。

提前致谢

2 个答案:

答案 0 :(得分:2)

您可以在名为image=的产品型号中为图像创建属性设置器:

def image=(uploaded_img)
  # Check if this product already has an image
  File.delete(full_image_path) if File.exist?(full_image_path)
  # Upload the new image
  image_path = Time.now.to_i.to_s + File.extname(uploaded_img.original_filename)
  File.open(full_image_path, 'w') do |file|
    file.write(uploaded_img.read)
  end
end

之后,删除控制器中的其余代码并使用@ product.update_attributes(params [:product])。 我没试过,但我认为它应该有用。

您是否知道有一些宝石可以轻松管理文件上传,例如https://github.com/jnicklas/carrierwavehttps://github.com/thoughtbot/paperclip

答案 1 :(得分:-1)

您应该尝试稍微重构控制器,控制器不应该运行任何其他任务,而不是指导模型和视图的流量。尝试将所有文​​件操作移动到单独的帮助程序。