图片不会用回形针保存,rails 4.2
picture won't save with paperclip, rails 4.2
我正在尝试允许用户上传图片。
我在这里通读了许多相同的问题并观看了几个教程...我仍然遗漏了一些东西。我看到图像文件参数在控制台中被拾取,但没有保存。
另一个问题,为什么rails希望方法是补丁而不是post?
感谢您的帮助。
这是我的模型图片:
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 %>
从控制台:
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" = ? LIMIT 1 [["id", 11]]
Completed 400 Bad Request in 3ms (ActiveRecord: 0.2ms)
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'
这样做:
def pic_params
params.require(:user).permit(upload: [:picture])
end
你目前遇到的问题是你的 params hash 期望...
"upload" => {
"picture => "..."
}
因为您使用的是 form_for @user
,它正在将参数哈希构建为...
"user" => {
"upload" => {
"picture" => {
....
}
}
}
这就是您收到错误的原因:
param is missing or the value is empty: 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 需要注意的重要一点是它的 面向对象 性质;每次创建记录时,它实际上是一个对象。您遇到的问题是您对要创建的对象感到困惑,导致您的参数散列不正确。
通过使用 pictures 控制器(而不是添加到 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
我正在尝试允许用户上传图片。
我在这里通读了许多相同的问题并观看了几个教程...我仍然遗漏了一些东西。我看到图像文件参数在控制台中被拾取,但没有保存。
另一个问题,为什么rails希望方法是补丁而不是post?
感谢您的帮助。
这是我的模型图片:
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 %>
从控制台:
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" = ? LIMIT 1 [["id", 11]] Completed 400 Bad Request in 3ms (ActiveRecord: 0.2ms)
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'
这样做:
def pic_params
params.require(:user).permit(upload: [:picture])
end
你目前遇到的问题是你的 params hash 期望...
"upload" => {
"picture => "..."
}
因为您使用的是 form_for @user
,它正在将参数哈希构建为...
"user" => {
"upload" => {
"picture" => {
....
}
}
}
这就是您收到错误的原因:
param is missing or the value is empty:
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 需要注意的重要一点是它的 面向对象 性质;每次创建记录时,它实际上是一个对象。您遇到的问题是您对要创建的对象感到困惑,导致您的参数散列不正确。
通过使用 pictures 控制器(而不是添加到 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