【问题标题】:Paperclip gem with Rails 4 doesn't save non-file fields带有 Rails 4 的 Paperclip gem 不保存非文件字段
【发布时间】:2013-08-26 21:21:20
【问题描述】:

我正在使用回形针 gem 构建一个 Rails 4 应用程序,用户可以在其中从具有其他几个字段(uploader_first_name、uploader_last_name、uploader_email)的表单上传视频文件。

回形针安装很顺利(虽然我需要添加gem 'protected_attributes' )并且我能够将文件保存到正确的位置并在视频表中创建相应的记录,但是所有 -paperclip 字段是null,我不知道为什么。

class Video < ActiveRecord::Base
    belongs_to :project
    attr_accessible :file
    has_attached_file :file, :url=>"/tmp/video_uploads", :path=>":rails_root/tmp/video_uploads"

end

class VideosController < ApplicationController
  def save
    @video = Video.create(params[:video])
    if @video.save
        redirect_to root_path
    else
        redirect_to "somewhere_else"
    end
  end

#I tried with this too...
  #private
    #def video_params
      #params.require(:video).permit( :uploader_first_name, :uploader_last_name, :uploader_email)
    #end
end

在视图中...

<h2>Upload your video</h2>
<% myclass = {:class=>'form-control'} %>
<%= form_for(:video, :url => {:action=>'save', :controller=>'videos'}, :html=>{:class=>'upload-form-js', :multipart=> true} ) do |f| %>

<div class="form-group">
<%= f.label(:uploader_first_name, "First Name") %>
<%= f.text_field(:uploader_first_name, myclass) %>
</div>

<div class="form-group">
<%= f.label(:uploader_last_name, "Last Name") %>
<%= f.text_field(:uploader_last_name, myclass) %>
</div>

<div class="form-group">
<%= f.label(:uploader_email, "Email") %>
<%= f.text_field(:uploader_email, myclass) %>
</div>

<div class="form-group">
    <label>Video File</label>
        <input type="file" name="video[file]" id="video_file"/></span>            
</div>

<%= f.submit('Upload', {class: 'btn btn-primary btn-block'}) %>
<% end %>

更新 1 我改成这个了……

class VideosController < ApplicationController
  def save
    @video = Video.create( video_params )
    if @video.save
        redirect_to root_path
    else
        redirect_to "somewhere_else"
    end
  end
  private
    def video_params
      params.require(:video).permit(:file, :uploader_first_name, :uploader_last_name, :uploader_email)
    end
end

...现在我得到 this 错误:

Errno::EISDIR in VideosController#save
Is a directory - /Applications/MAMP/htdocs/clippo2/tmp/video_uploads

我不想让 url/path 指向一个目录吗?

更新 2 我将视频模型更改为...

has_attached_file :file, :url=>"/tmp/video_uploads/:basename.:extension", :path=>":rails_root/tmp/video_uploads/:basename.:extension"

...现在没有错误,文件被保存到正确的目录,并且相应的字段添加到新行,但所有其他字段仍然为 NULL(原始问题)。

更新 3 我打开了调试器,这是我尝试上传文件后看到的内容。它看起来像一个严重的参数错误,但我不知道如何修复它:

Started POST "/videos/save" for 127.0.0.1 at 2013-08-27 09:21:34 -0400
Processing by VideosController#save as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"es4wPqFr9xPBUFsbHQR/gAzofDC+ZwYsiiJ7RAQZUHk=", "video"=>{"uploader_first_name"=>"adsfasdf", "uploader_last_name"=>"asdfasdf", "uploader_email"=>"asdfasdf", "file"=>#<ActionDispatch::Http::UploadedFile:0x007fc4782e31e8 @tempfile=#<Tempfile:/var/folders/f2/jhv7xx0j3hlckhcg_jbv6hr00000gn/T/RackMultipart20130827-89636-188f0hs>, @original_filename="sample_iPod.m4v", @content_type="video/mp4", @headers="Content-Disposition: form-data; name=\"video[file]\"; filename=\"sample_iPod.m4v\"\r\nContent-Type: video/mp4\r\n">, "project_hashed_id"=>"1377539908"}, "commit"=>"Upload"}
{"utf8"=>"✓", "authenticity_token"=>"es4wPqFr9xPBUFsbHQR/gAzofDC+ZwYsiiJ7RAQZUHk=", "video"=>{"uploader_first_name"=>"adsfasdf", "uploader_last_name"=>"asdfasdf", "uploader_email"=>"asdfasdf", "file"=>#<ActionDispatch::Http::UploadedFile:0x007fc4782e31e8 @tempfile=#<Tempfile:/var/folders/f2/jhv7xx0j3hlckhcg_jbv6hr00000gn/T/RackMultipart20130827-89636-188f0hs>, @original_filename="sample_iPod.m4v", @content_type="video/mp4", @headers="Content-Disposition: form-data; name=\"video[file]\"; filename=\"sample_iPod.m4v\"\r\nContent-Type: video/mp4\r\n">, "project_hashed_id"=>"1377539908"}, "commit"=>"Upload", "controller"=>"videos", "action"=>"save"}
Unpermitted parameters: project_hashed_id
WARNING: Can't mass-assign protected attributes for Video: uploader_first_name, uploader_last_name, uploader_email
    app/controllers/videos_controller.rb:6:in `save'
  [1m[35m (0.2ms)[0m  BEGIN
  [1m[36mSQL (0.3ms)[0m  [1mINSERT INTO `videos` (`created_at`, `file_content_type`, `file_file_name`, `file_file_size`, `file_updated_at`, `updated_at`) VALUES ('2013-08-27 13:21:34', 'video/mp4', 'sample_iPod.m4v', 2236480, '2013-08-27 13:21:34', '2013-08-27 13:21:34')[0m
  [1m[35m (9.0ms)[0m  COMMIT
Redirected to http://localhost:3000/
Completed 302 Found in 21ms (ActiveRecord: 9.5ms)

【问题讨论】:

  • 当您说您“尝试”了注释掉的代码时,您究竟是如何合并它的?
  • 我取消了它的注释并将Video.create(params[:video]) 替换为Video.create(video_params)。这并没有引发错误,但它导致文件没有被保存,也没有导致其他字段被保存。
  • 好的,没有require,你将不会得到这些字段,如果save 失败,你将不会得到 any 字段.所以你需要保留require,我认为,并找出save在这种情况下失败的原因。
  • @PeterAlfvin 我想我几乎已经知道发生了什么。我在日志中发现了相关错误,但我不完全确定如何解释它:“警告:无法为视频批量分配受保护的属性:uploader_first_name、uploader_last_name、uploader_email”
  • 你知道Unpermitted parameters: project_hashed_id是什么吗?

标签: ruby-on-rails ruby paperclip ruby-on-rails-4


【解决方案1】:

欢迎使用 rails 4. 'attr_accessible' 被强参数替换。
http://api.rubyonrails.org/classes/ActionController/StrongParameters.html

更新。你可以试试这个吗?

def create
  @video = Video.create(video_params)
end

private

def video_params
  params.require(:video).permit(:file, :uploader_first_name, :uploader_last_name, :uploader_email)
end

【讨论】:

  • @x3qt 我注意到您的.permit() 包含:file。我想知道我是否应该尝试一下?
  • @Emerson 是的,包括:file
  • @PeterAlfvin 我添加了:file,现在它似乎想要工作,但现在我从(我认为)回形针收到错误。请参阅上面的更新。
【解决方案2】:

我知道发生了什么。因为我在模型中使用了attr_accessible,所以强大的参数妨碍了我。而不是摆弄 require() 和 permit() 我完全删除了它们并将缺少的字段添加到 attr_accessible 现在它可以工作了:

class Video < ActiveRecord::Base
    belongs_to :project
    attr_accessible :file, :uploader_first_name, :uploader_last_name, :project_hashed_id, :uploader_email, :rating
    has_attached_file :file, :url=>"/tmp/video_uploads/:basename.:extension", :path=>":rails_root/tmp/video_uploads/:basename.:extension"
end

class VideosController < ApplicationController
  def save
    logger.debug( params )
    #@video = Video.new( video_params )
    @video = Video.new( params[:video])
    if @video.save
        redirect_to root_path
    else
        redirect_to "somewhere_else"
    end
  end
end

我意识到 attr_accessible 在 Rails 4 中被强参数取代,但没有它我无法让回形针工作。如果有人能告诉我怎么做,我很想知道。

更新 我完全删除了attr_accessible,只使用了强参数...

class VideosController < ApplicationController

  def save
    logger.debug( params )
    @video = Video.new( video_params )
    if @video.save
        redirect_to root_path
    else
        redirect_to "somewhere_else"
    end
  end

  private
    def video_params
      #params.require(:video).permit(:file, :uploader_first_name, :uploader_last_name, :uploader_email, :project_hashed_id)
      params.require(:video).permit!
    end

end

...它可以工作,但是 您必须记住删除 protected_attributes gem 并重新启动 rails s 以使其生效(这个 n00b 错误花了我 45 分钟!)

这个故事的寓意:不要将attr_accessible 与强参数混用。做一个或另一个,回形针使用强参数。

【讨论】:

  • 您是否尝试取出 attr_accessible 并保留强参数?
  • 根据stackoverflow.com/questions/17737709/…,它似乎确实有效。 :-)
  • @PeterAlfvin 我要试试。
  • @PeterAlfvin 我试过了,但没用。我用详细信息更新了答案。
  • @PeterAlfvin 误报:有效!!我忘了卸载 protected_attributes gem。感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-25
相关资源
最近更新 更多