简体   繁体   English

图片不能用回形针保存,导轨4.2

[英]picture won't save with paperclip, rails 4.2

I'm trying to allow a user to upload a picture. 我正在尝试允许用户上传图片。

I've read through many of the same questions here and watched several tutorials...I'm still missing something. 我在这里阅读了许多相同的问题,并观看了一些教程...我仍然缺少一些东西。 I see image file parameters are picked up in the console, but are not saved. 我看到图像文件参数是在控制台中拾取的,但是没有保存。

Another question, why does rails want the method to be a patch instead of a post? 另一个问题,为什么Rails希望该方法是补丁而不是帖子?

Thanks for your help. 谢谢你的帮助。

Here is my model Picture: 这是我的模特照片:

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

Here is my controller: 这是我的控制器:

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

And here is my view page: 这是我的查看页面:

    <%= 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 %>

From the console: 从控制台:

Started PATCH "/MeetSomeone/upload_image?user_ud=11" for ::1 at 2015-12-24 01:22:38 -0800 Processing by UsersController#upload_image as HTML Parameters: {"utf8"=>"✓", "authenticity_token"=>"/Fhkg2t1vivVlIisE5J5ndRO63PpOELhEwKCLfEELEWvb1XNUvV8HD5VFTnMswCGp+7v8W/wqiuQtOd4GGw2oA==", "user"=>{"upload"=>{"picture"=>#, @original_filename="scott.jpeg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\\"user[upload[picture]]\\"; filename=\\"scott.jpeg\\"\\r\\nContent-Type: image/jpeg\\r\\n">}}, "commit"=>"Upload", "user_ud"=>"11"} User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? 在2015年12月24日01:22:38 -0800以:: 1的价格开始为:: 1的PATCH“ / MeetSomeone / upload_image?user_ud = 11”,由UsersController#upload_image处理为HTML参数:{“ utf8” =>“✓”,“ authenticity_token “ =>” / Fhkg2t1vivVlIisE5J5ndRO63PpOELhEwKCLfEELEWvb1XNUvV8HD5VFTnMswCGp + 7v8W / wqiuQtOd4GGw2oA ==“,” user“ => {” upig“ => {”图片“ _ @”,例如“ @”图片“ ,@ headers =“ Content-Disposition:form-data; name = \\” user [upload [picture]] \\“; filename = \\” scott.jpeg \\“ \\ r \\ n内容类型:image / jpeg \\ r \\ n “>}},”提交“ =>”上传“,” user_ud“ =>” 11“}用户负载(0.2毫秒)选择“用户”。*从“用户”中,在“用户”中。“ id” =? LIMIT 1 [["id", 11]] Completed 400 Bad Request in 3ms (ActiveRecord: 0.2ms) LIMIT 1 [[“ id”,11]]在3毫秒内完成了400个错误请求(ActiveRecord:0.2毫秒)

ActionController::ParameterMissing (param is missing or the value is empty: upload): app/controllers/users_controller.rb:52:in pic_params' app/controllers/users_controller.rb:46:in upload_image' ActionController :: ParameterMissing(缺少参数或值为空:上载):app / controllers / pic_params' app/controllers/users_controller.rb:46:in :52:在pic_params' app/controllers/users_controller.rb:46:in upload_image中

Do this: 做这个:

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

The problem you have currently is that you're params hash is expecting... 您当前遇到的问题是,您正在参数哈希中期望...

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

Because you're using form_for @user , it's building the params hash as... 因为您使用的是form_for @user ,所以它将params哈希构建为...

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

This is why you're getting the error: 这就是为什么出现错误的原因:

param is missing or the value is empty: upload 参数丢失或值为空: upload

Your structure is really bad (I've corrected some of it below); 您的结构确实很糟糕(我已经在下面更正了一些内容); you'd do well to read up on the params class to see how it works. 您最好阅读params类以了解其工作原理。


I would personally do the following: 我个人将执行以下操作:

#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 %>

This will be accessible at url.com/pictures/new 可通过url.com/pictures/new访问

I know it's not adherent to the structure of your application; 我知道它不符合您的应用程序结构; I'll explain how you'd get it working with your app in a second. 我将在稍后说明您将如何使其与您的应用一起使用。

The important thing to note about Rails is its object orientated nature; 关于Rails的重要注意事项是其面向对象的特性。 every time you create a record, it's actually an object . 每次创建记录时,它实际上都是一个对象 The problem you have is that you're getting confused with which object you're trying to create, leading your params hash to be incorrect. 您遇到的问题是,您对尝试创建的对象感到困惑,导致参数哈希不正确。

By using a pictures controller (rather than adding to the users controller), you are able to create a Picture object on the back of the user association. 通过使用图片控制器(而不是添加到users控制器),您可以在用户关联的背面创建一个Picture对象。 The way you're doing it currently would require you to use accepts_nested_attributes_for , which can get tricky: 当前您的操作方式需要您使用accepts_nested_attributes_for ,这可能会很棘手:


The way you should be doing what you're doing is to use accepts_nested_attributes_for - which basically means that you're able to send nested data to an associated model. 应该做的事情是使用accepts_nested_attributes_for这基本上意味着您可以将嵌套数据发送到关联的模型。

Since you wish to use your users controller, it would be better for you to send the picture object as nested -- 由于您希望使用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 

This will allow you to use: 这将允许您使用:

#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 %>

Finally, a pro-tip I give out is the paperclip_defaults option for Paperclip: 最后,我给出的一个专业提示是Paperclip的paperclip_defaults选项:

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

This will set the default options for any Paperclip enabled model you have (which can be overridden of course). 这将为您拥有的任何启用Paperclip模型设置默认选项(当然可以覆盖)。

Ultimately, it means that you're able to clean up your models quite simply: 最终,这意味着您可以非常简单地清理模型:

#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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM