这几天困扰着我。我试过不同的方法。所以我会选择最简单的形式,这应该是有效的,但不是。
我有两个型号。 Institute
和VirtualTour
。
class Institute < ActiveRecord::Base
mount_uploader :virtual_images, VirtualPicUploader
has_many :virtual_tours, dependent: :destroy
accepts_nested_attributes_for :virtual_tours,allow_destroy: true
end
class VirtualTour < ActiveRecord::Base
belongs_to :institute
mount_uploader :image, VirtualPicUploader
end
我对devise
学院很有兴趣。这个更简单的版本没有考虑强参数,所以我会保持这样。
def account_update
default_params.permit!
end
在编辑时会发生此上传,这就是使用account_update的原因。
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put , multipart: true }) do |f| %>
<%= f.fields_for :virtual_tours do |ff| %>
<%= ff.file_field :image, multiple: true %>
<%= ff.hidden_field :institute_id, value: f.object.id %>
<% end %>
<% end %>
我提交时在浏览器中收到此错误。
no implicit conversion of nil into String
def cache_path
File.expand_path(File.join(cache_dir, cache_name), root)
end
在日志中, 在91ms内完成500内部服务器错误(ActiveRecord:1.8ms)
TypeError (no implicit conversion of nil into String):
carrierwave (0.10.0) lib/carrierwave/uploader/cache.rb:159:in `join'
carrierwave (0.10.0) lib/carrierwave/uploader/cache.rb:159:in `cache_path'
carrierwave (0.10.0) lib/carrierwave/uploader/cache.rb:131:in `block in cache!'
carrierwave (0.10.0) lib/carrierwave/uploader/callbacks.rb:17:in `with_callbacks'
carrierwave (0.10.0) lib/carrierwave/uploader/cache.rb:122:in `cache!'
carrierwave (0.10.0) lib/carrierwave/mount.rb:329:in `cache'
carrierwave (0.10.0) lib/carrierwave/mount.rb:163:in `image='
carrierwave (0.10.0) lib/carrierwave/orm/activerecord.rb:39:in `image='
activerecord (4.2.4) lib/active_record/attribute_assignment.rb:54:in `public_send'
activerecord (4.2.4) lib/active_record/attribute_assignment.rb:54:in `_assign_attribute'
activerecord (4.2.4) lib/active_record/attribute_assignment.rb:41:in `block in assign_attributes'
actionpack (4.2.4) lib/action_controller/metal/strong_parameters.rb:185:in `each_pair'
actionpack (4.2.4) lib/action_controller/metal/strong_parameters.rb:185:in `each_pair'
activerecord (4.2.4) lib/active_record/attribute_assignment.rb:35:in `assign_attributes'
activerecord (4.2.4) lib/active_record/nested_attributes.rb:513:in `assign_to_or_mark_for_destruction'
activerecord (4.2.4) lib/active_record/nested_attributes.rb:479:in `block in assign_nested_attributes_for_collection_association'
activerecord (4.2.4) lib/active_record/nested_attributes.rb:460:in `each'
过去两天一直在研究这个问题。任何帮助将不胜感激。
答案 0 :(得分:12)
我遇到了同样的问题。我用它来修复它
mount_uploaders
不是mount_uploader
答案 1 :(得分:1)
我已将文档here包含在内以供参考。
入门可以帮助我们开始。我假设您尝试同时上传多张图片时发生错误?
尽管如此,这是我在使用载波实现文件上传时所采取的步骤。
CarrierWave的documentation引导我们完成将其与我们的应用程序集成的过程,但这里列出了基本步骤:
将上传器与模型集成。 假设我们想要将配置文件照片添加到具有User模型的应用程序,我们可以先将gem添加到我们的Gemfile中来安装gem:
gem "carrierwave"
要么
gem 'carrierwave', github: 'carrierwaveuploader/carrierwave'
用于多张图片上传。
使用bundle命令下载并安装gem:
$ bundle
Installing carrierwave ...
....
现在我们需要一个可以存储个人资料照片的上传器。我们可以使用CarrierWave附带的生成器创建一个:
$ rails generate uploader ProfilePhoto
这将在app / uploaders / profile_photo_uploader.rb中创建一个新文件。如果我们查看该文件,我们会看到许多配置上传器的选项,但现在我们关注文件的存储位置:
class ProfilePhotoUploader < CarrierWave::Uploader::Base
storage :file
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
end
storage :file
选项指定文件本地存储在Web服务器(即我们的笔记本电脑)上。这对于开发来说很好,但是当我们部署到生产服务器时,我们希望稍后更改它。
store_dir
方法指定我们可以找到上传文件的目录。默认情况下,路径将从公共文件夹开始,以便可以访问上载的文件。如果我们在User模型上安装此上传器,则完整路径为/public/uploads/user/profile_photo/#{user.id}/file_name
。每个用户都有自己的目录,以防止其他用户覆盖同名文件。
现在我们有了上传器,我们需要在users表中添加一列,以便我们可以存储文件的位置。我们创建一个迁移来添加profile_photo
列:
$ rails generate migration add_profile_photo_to_users
我们可以修改我们的迁移文件以包含以下内容:
class AddProfilePhotoToUsers < ActiveRecord::Migration
def change
add_column :users, :profile_photo, :string
end
end
运行此迁移后,我们现在可以存储与每个用户关联的个人资料照片。
最后一步是通过ProfilePhotoUploader
列附加我们使用User
模型创建的profile_photo
。我们可以将以下行添加到User
模型中:
class User < ActiveRecord::Base
mount_uploader :profile_photo, ProfilePhotoUploader
end
现在我们可以在profile_photo
模型上调用User
方法,它会返回上传文件的详细信息。
要完成个人资料照片上传功能,我们还需要在用户注册表单上添加一个位置,以允许用户在其计算机上选择图像。使用form_for
,我们可以添加以下内容:
<%= f.file_field :profile_photo %>
这些方法会将<input type="file">
元素添加到表单中,以便它向用户显示一个用于选择文件的对话框。
最后一步是确保个人资料照片可以通过用户控制器上的强参数。如果我们使用Devise,我们可以使用我们可以在app/controllers/application_controller.rb
中定义的前置过滤器为注册过程注入新属性:
class ApplicationController < ActionController::Base
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) << :profile_photo
end
end
此时,用户应该能够在创建或更新注册时选择个人资料照片,并且图像将与用户相关联。
注意:请注意,carrierwave将使用rails使用的命名约定。如果您将文件命名为Uploader类AvatarUploader,它将查找以avatar avatar_uploader.rb
命名的文件(奇异的模型)。
更新:对于多个图片上传者,请确保您的模型中有mount_uploaders
而不是单数形式。
答案 2 :(得分:0)
更改<%= ff.file_field :image, multiple: true %>
到<%= ff.file_field :image %>
multiple: true
不需要添加字段。