Carrierwave 保存对象而不是 db 中的文件名或 mount_uploader 不起作用
Carrierwave save object instead filename in db or mount_uploader doesn't work
我使用 Carrierwave gem 上传文件,但我遇到了问题。控制器不会将头像保存在数据库中,尽管该对象来自视图的参数。如果我从我的模型中删除 mount_uploader,Carrierwave 在数据库中保存对象而不是文件名。我该如何解决?
我的user_controller.rb
class UsersController < ApplicationController
before_action :set_user
def show
end
def edit
end
def update
if @user.update(users_params)
redirect_to user_path(current_user.id)
else
puts @user.inspect
flash.now[:alert]= 'Something wrong'
render :edit
end
end
def set_user
@user = User.find(params[:id])
end
def users_params
params.require(:user).permit(:avatar)
end
def new
end
end
我的user.rb模特
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :omniauthable,
omniauth_providers: [:facebook]
has_one :account, dependent: :destroy
mount_uploader :avatar, AvatarUploader
end
edit.html.haml
.container
%h1 Edit
= form_for @user, html: { :multipart => true } do |f|
= f.label :id
= f.file_field :avatar
= f.submit
avatar_uploader.rb
class AvatarUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
storage :file
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
version :thumb do
process resize_to_fit: [50, 50]
end
def extension_whitelist
%w(jpg jpeg gif png)
end
end
对象正在保存在数据库中,因为您在参数中传递了完整的头像对象。
安装上传器后
class User < ActiveRecord::Base
mount_uploader :avatar, AvatarUploader
end
并创建并保存一个新用户
u = User.new
u.avatar = params[:file] # Assign a file like this
u.save!
分配了整个头像对象,然后您可以访问该对象的各种方法来获取字段,例如:
u.avatar.url # => '/url/to/file.png'
u.avatar.current_path # => 'path/to/file.png'
u.avatar_identifier # => 'file.png'
如果你只想在数据库中保存文件名,而不是将 avatar
传递给用户参数,你可以只传递 avatar.identifier
相应的文件仍将由头像上传者存储
或者您可以自己创建上传器实例来做到这一点,例如:
uploader = AvatarUploader.new
uploader.store!(my_file)
更新:
由于您使用的是 Devise,因此您必须以不同的方式访问参数。所以 User.rb
应该是这样的:
在Rails 5:
class User < ActiveRecord::Base
mount_uploader :avatar, AvatarUploader
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :remember_me, :avatar, :avatar_cache, :remove_avatar
end
在Rails 4:
而不是模型中的 attr_accessible,必须在应用程序控制器中将参数列入白名单
class ApplicationController < ActionController::Base
before_filter :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up) { |u| u.permit(:username, :email, :password,
:password_confirmation, :remember_me, :avatar, :avatar_cache, :remove_avatar) }
devise_parameter_sanitizer.permit(:account_update) { |u| u.permit(:username, :email, :password,
:password_confirmation, :current_password, :avatar, :avatar_cache, :remove_avatar) }
end
end
我使用 Carrierwave gem 上传文件,但我遇到了问题。控制器不会将头像保存在数据库中,尽管该对象来自视图的参数。如果我从我的模型中删除 mount_uploader,Carrierwave 在数据库中保存对象而不是文件名。我该如何解决?
我的user_controller.rb
class UsersController < ApplicationController
before_action :set_user
def show
end
def edit
end
def update
if @user.update(users_params)
redirect_to user_path(current_user.id)
else
puts @user.inspect
flash.now[:alert]= 'Something wrong'
render :edit
end
end
def set_user
@user = User.find(params[:id])
end
def users_params
params.require(:user).permit(:avatar)
end
def new
end
end
我的user.rb模特
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :omniauthable,
omniauth_providers: [:facebook]
has_one :account, dependent: :destroy
mount_uploader :avatar, AvatarUploader
end
edit.html.haml
.container
%h1 Edit
= form_for @user, html: { :multipart => true } do |f|
= f.label :id
= f.file_field :avatar
= f.submit
avatar_uploader.rb
class AvatarUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
storage :file
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
version :thumb do
process resize_to_fit: [50, 50]
end
def extension_whitelist
%w(jpg jpeg gif png)
end
end
对象正在保存在数据库中,因为您在参数中传递了完整的头像对象。
安装上传器后
class User < ActiveRecord::Base
mount_uploader :avatar, AvatarUploader
end
并创建并保存一个新用户
u = User.new
u.avatar = params[:file] # Assign a file like this
u.save!
分配了整个头像对象,然后您可以访问该对象的各种方法来获取字段,例如:
u.avatar.url # => '/url/to/file.png'
u.avatar.current_path # => 'path/to/file.png'
u.avatar_identifier # => 'file.png'
如果你只想在数据库中保存文件名,而不是将 avatar
传递给用户参数,你可以只传递 avatar.identifier
相应的文件仍将由头像上传者存储
或者您可以自己创建上传器实例来做到这一点,例如:
uploader = AvatarUploader.new
uploader.store!(my_file)
更新:
由于您使用的是 Devise,因此您必须以不同的方式访问参数。所以 User.rb
应该是这样的:
在Rails 5:
class User < ActiveRecord::Base
mount_uploader :avatar, AvatarUploader
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :remember_me, :avatar, :avatar_cache, :remove_avatar
end
在Rails 4: 而不是模型中的 attr_accessible,必须在应用程序控制器中将参数列入白名单
class ApplicationController < ActionController::Base
before_filter :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up) { |u| u.permit(:username, :email, :password,
:password_confirmation, :remember_me, :avatar, :avatar_cache, :remove_avatar) }
devise_parameter_sanitizer.permit(:account_update) { |u| u.permit(:username, :email, :password,
:password_confirmation, :current_password, :avatar, :avatar_cache, :remove_avatar) }
end
end