使用paperclip,rails 4.2

时间:2015-12-24 09:41:59

标签: ruby-on-rails image paperclip

我正在尝试允许用户上传图片。

我在这里阅读了很多相同的问题并观看了几个教程......我仍然遗漏了一些东西。我看到图像文件参数在控制台中被选中,但是没有保存。

另一个问题,为什么rails希望该方法是补丁而不是帖子?

感谢您的帮助。

这是我的模特图片:

class Picture < ActiveRecord::Base

    has_attached_file :picture, styles: { medium: "300x300", thumb: "100x100#" }

    validates_attachment_content_type :picture, :content_type => ["image/jpg", "image/jpeg", "image/png", "image/gif"]

    belongs_to :user
end

这是我的控制器:

def upload_image
    User.find(session[:user_id]).pictures.create(pic_params)
    redirect_to :back
end

private
def pic_params
    params.require(:upload).permit(:picture)
end

这是我的观点页面:

    <%= form_for(@user, :html => {:multipart => true}, :url => { :action => 'upload_image', :user_ud => @user.id }) do |f| %>
        <%= f.file_field "upload[picture]" %>
        <%= f.submit :Upload %>
    <% end %>

从控制台:

  

启动PATCH“/ MeetSomeone / upload_image?user_ud = 11”for :: 1 at   2015-12-24 01:22:38 -0800由UsersController处理#upload_image   作为HTML参数:{“utf8”=&gt;“✓”,   “authenticity_token”=&gt; “中/ Fhkg2t1vivVlIisE5J5ndRO63PpOELhEwKCLfEELEWvb1XNUvV8HD5VFTnMswCGp + 7v8W / wqiuQtOd4GGw2oA ==”,   “用户”=&GT; { “上传”=&GT; { “图片”=&GT;#,   @ original_filename =“scott.jpeg”,@ content_type =“image / jpeg”,   @ headers =“Content-Disposition:form-data;   名= \ “用户[上传[图象]] \”;   filename = \“scott.jpeg \”\ r \ nConContent-Type:image / jpeg \ r \ n“&gt;}},   “commit”=&gt;“上传”,“user_ud”=&gt;“11”}用户加载(0.2ms)SELECT   “users”。* FROM“users”WHERE“users”。“id”=?限制1 [[“id”,11]]   在3ms内完成400 Bad Request(ActiveRecord:0.2ms)

     

ActionController :: ParameterMissing(param丢失或值为   empty:upload):app / controllers / users_controller.rb:52:in   pic_params' app/controllers/users_controller.rb:46:in upload_image'

1 个答案:

答案 0 :(得分:0)

这样做:

def pic_params
   params.require(:user).permit(upload: [:picture])
end

您目前遇到的问题是,您正在考虑哈希期待...

"upload" => {
   "picture => "..."
}

因为您正在使用form_for @user,所以它会将params哈希构建为......

"user" => {
  "upload" => {
     "picture" => {
       ....
     }
  }
}

这就是您收到错误的原因:

  

param丢失或值为空:upload

你的结构真的很糟糕(我已经纠正了下面的一些内容);您最好阅读params class以了解其运作方式。

我个人会做以下事情:

#config/routes.rb
resources :pictures #-> url.com/pictures/new

#app/controllers/pictures_controller.rb
class PicturesController < ApplicationController
   before_action :user

   def new
     @picture = @user.pictures.new
   end

   def create
     @picture = @user.pictures.new pic_params
     @picture.save
   end

   private

   def pic_params
      params.require(:picture).permit(:image)
   end

   def user
      @user = User.find params[:session_id]
   end
end

#app/views/pictures/new.html.erb
<%= form_for @picture, multipart: true do |f| %>
   <%= f.file_field :picture %>
   <%= f.submit %>
<% end %>

可在url.com/pictures/new

访问此页面

我知道它并不依赖于您的应用程序结构;我将解释您如何在一秒钟内使用您的应用程序。

关于Rails的重要一点是它的面向对象的性质;每次创建记录时,它实际上都是对象。您遇到的问题是,您对尝试创建的对象感到困惑,导致您的参数哈希不正确。

通过使用图片控制器(而不是添加到users控制器),您可以在用户关联的背面创建Picture对象。您目前的做法是要求您使用accepts_nested_attributes_for,这可能会变得棘手:

应该做你正在做的事情的方式是使用accepts_nested_attributes_for - 这基本上意味着你能够将嵌套数据发送到相关模型

由于您希望使用users控制器,最好将picture对象作为嵌套发送 -

#config/routes.rb
resources :users do
   match :upload_image, via: [:get, :patch], on: :collection #-> url.com/users/upload_image #-> you're using session[:user_id] so no need for member route
end

#app/models/user.rb
class User < ActiveRecord::Base
   has_one :picture
   accepts_nested_attributes_for :picture
end

#app/controllers/users_controller.rb
class UsersController < ApplicationController
   before_action :set_user

   def upload_image
      if request.get?
         @user.build_picture unless @user.picture
      elsif request.patch?
         @user.update pic_params
         redirect_to @user
      end
   end

   private

   def pic_params
      params.require(:user).permit(picture_attributes: [:picture])
   end

   def set_user
      @user = User.find params[:user_id] #-> this is 
   end
end 

这将允许您使用:

#app/views/users/upload_image.html.erb
<%= form_for @user do |f| %>
   <%= f.fields_for :picture do |p| %>
      <%= p.file_field :picture %>
   <% end %>
   <%= f.submit %>
<% end %>

最后,我给出的专业提示是Paperclip的paperclip_defaults选项:

#config/application.rb
...
config.paperclip_defaults = {
   styles: { medium: "300x300", thumb: "100x100#" }
}

这将为您拥有的任何Paperclip启用的模型设置默认选项(当然可以覆盖它)。

最终,这意味着您可以非常简单地清理模型:

#app/models/picture.rb
class Picture < ActiveRecord::Base
    belongs_to :user

    has_attached_file :picture
    validates :picture, content_type: { content_type: ["image/jpg", "image/jpeg", "image/png", "image/gif"] }
end