0

我创建了一个表单,用户可以在其中上传文件: :File是我的列Setting 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"}

我想错误是由于参数而发生的?

如果您想查看我的控制器:

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
4

2 回答 2

2

问题是您如何管理上传:您不能只将 aninput[type="file"]产生的内容传递给数据库,尤其是 String 类型的字段:当您上传文件时,它仅作为临时文件提供,您必须将其保存在某个地方,并制作数据库记住它的路径。

您可以查看 rails guides 关于如何处理上传的内容。使用推荐的方法,您将从模型(和 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 ] )

有关详细信息,请参阅回形针文档。

编辑:在第一段中添加了有关临时文件的更多信息

于 2013-09-19T14:13:21.213 回答
0

您应该使用多部分形式上传文件:-

form_for @user, :html => { :multipart => true } do |f...
于 2013-09-19T12:27:43.903 回答