简单上传文件的问题

时间:2013-09-19 12:10:34

标签: ruby-on-rails ruby ruby-on-rails-3

我创建了一个用户可以上传文件的表单::FileSetting model

中的一列
<%= form_for(@setting) do |f| %>

  <div class="field">
    <%= f.label 'Patientendaten' %>
    <%= f.file_field :file %>
  </div>
.......

当我不上传文件并只编辑其他“设置”时没有问题。但是当我尝试上传文件时,我收到了这个错误:

 NoMethodError in SettingsController#update
  undefined method `name' for nil:NilClass

  app/controllers/settings_controller.rb:72:in `block in update'
  app/controllers/settings_controller.rb:71:in `update'

相应的参数是:

 {"utf8"=>"✓",
 "_method"=>"put",
 "authenticity_token"=>"eFchgMpE0A46jQI0asmiR2wH+4kq/vmSzDchlBmMJaA=",
 "setting"=>{"adobe"=>"",
 "file"=>#<ActionDispatch::Http::UploadedFile:0x3764b98 @original_filename="prawn.rb",
 @content_type="application/octet-stream",
 @headers="Content-Disposition: form-data; name=\"setting[file]\";              filename=\"prawn.rb\"\r\nContent-Type: application/octet-stream\r\n",
 @tempfile=#<File:C:/Users/STADLE~1/AppData/Local/Temp/RackMultipart20130919-6776-   1bs1n2d>>,
 "treiber"=>"",
 "port"=>"",
 "druckername"=>"",
 "bild"=>"C:/geburtstag/app/vorderseite/default.jpg",
 "anrede"=>"",
 "text"=>""},
 "commit"=>"Speichern",
 "id"=>"1"}

我认为错误的发生是因为params?

如果你想看我的控制器:

def update
@setting = Setting.find(params[:id])


respond_to do |format|
  if @setting.update_attributes(params[:setting])

    pdf = Prawn::Document.new(:page_size=> "A4",:margin => 0)
    pdf.image @setting.bild ,:at  => [0, Prawn::Document::PageGeometry::SIZES["A4"][1]],:fit => Prawn::Document::PageGeometry::SIZES["A4"]
    Dir.chdir  Rails.root.to_s + '/vorderseite' do |dir|
    pdf.render_file "vorderseite.pdf"
    end


    format.html { redirect_to patients_path, notice: 'Setting was successfully updated.' }
    format.json { head :no_content }
  else
    format.html { render action: "edit" }
    format.json { render json: @setting.errors, status: :unprocessable_entity }
  end
end
end

型号:

class Setting < ActiveRecord::Base
 attr_accessible :anrede, :text, :adobe , :bild, :treiber, :port, :druckername, :file
  before_save :default_values
   def default_values 
   self.bild = Rails.root.to_s + '/vorderseite/default.jpg' if self.bild.blank?
  end
end

2 个答案:

答案 0 :(得分:2)

问题在于你如何管理上传:你不能只将input[type="file"]生成的内容传递给数据库,特别是String类型的字段:当你上传文件时,它只作为临时文件提供,你必须坚持到某个地方,让数据库记住它的路径。

你可以see what rails guides has to say about how to handle uploads。使用推荐的方法,您将从模型中删除“file”属性(和attr_accessible),在控制器中的params中获取上传生成的IO,将其内容写入文件系统中的某个位置,然后保存文件路径(可能在bild属性中。

但这可能非常耗时且容易出现安全问题(例如,您必须特别注意阻止某人上传名为../../../../../../../../etc/passwords的文件,该文件会覆盖您的服务器密码文件。)

在实际情况中,我们经常使用第三方库来处理上传,例如PaperclipCarrierwave

例如,使用Paperclip,您可以在模型中添加类似的内容:

class Setting < ActiveRecord::Base
 attr_accessible :anrede, :text, :adobe , :bild, :treiber, :port, :druckername

 has_attached_file :bild
end

(前提是您的上传字段为bild)。

这将让您完成目前的工作:

@setting.update_attribute( params[ :setting ] )

有关详细信息,请参阅paperclip文档。

编辑:在第一段

中添加了有关临时文件的更多信息

答案 1 :(得分:0)

您应该使用多部分表单上传文件: -

form_for @user, :html => { :multipart => true } do |f...