简体   繁体   English

Rails 4 - Carrierwave图像无法上传

[英]Rails 4 - Carrierwave image not uploading

UPDATE : Thanks everyone for the help in trying to figure this out. 更新 :感谢大家帮助我们解决这个问题。 I decided to give up trying to learn and added another image attribute to the profile model. 我决定放弃尝试学习并为配置文件模型添加另一个图像属性。 This will have to do for now. 这将是现在必须做的。

Im trying to make an app in rails 4. 我试图在rails 4中制作应用程序。

I have a user model, which has an avatar attribute on it. 我有一个用户模型,上面有一个头像属性。

I also have a profile model. 我也有个人资料模型。

User :has one profile Profile :belongs to User 用户:有一个个人资料个人资料:属于用户

The reason I split them is because profile contains all the variables and user contains all the fixed attributes that cannot be changed without admin permission. 我拆分它们的原因是因为配置文件包含所有变量,而用户包含所有未经管理员权限无法更改的固定属性。

The exception is that my user model has an avatar (image) attribute which I want to allow users to change. 例外是我的用户模型具有我想允许用户更改的头像(图像)属性。

I have user carrierwave in other parts of my code and it works. 我在我的代码的其他部分有用户carrierwave,它的工作原理。 However, something is wrong in this use case. 但是,这个用例有些不对劲。

I have an avatar uploader with: 我有一个头像上传者:

class AvatarUploader < CarrierWave::Uploader::Base

  # Include RMagick or MiniMagick support:
  # include CarrierWave::RMagick
  include CarrierWave::MiniMagick

  # Choose what kind of storage to use for this uploader:
  # storage :file
  storage :fog

  # Override the directory where uploaded files will be stored.
  # This is a sensible default for uploaders that are meant to be mounted:
  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

  def cache_dir
    "#{Rails.root}/tmp/uploads"
  end

  # Provide a default URL as a default if there hasn't been a file uploaded:
  # def default_url
  #   # For Rails 3.1+ asset pipeline compatibility:
  #   # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
  #
  #   "/images/fallback/" + [version_name, "default.png"].compact.join('_')
  # end

  # Process files as they are uploaded:
  # process :scale => [200, 300]
  #
  # def scale(width, height)
  #   # do something
  # end

  # Create different versions of your uploaded files:
  # version :thumb do
  #   process :resize_to_fit => [50, 50]
  # end

  process :resize_to_fit => [800, 800]
  # Create different versions of your uploaded files:
  version :thumb do
    process :resize_to_fill => [200,200]
  end

  version :profile do
    process :resize_to_fill => [345,245]
  end

  version :wide do
    process :resize_to_fill => [951,245]
  end

  version :preview do
    process :resize_to_fill => [90,90]
  end

  version :small do
    process :resize_to_fill => [35,35]
  end


  # Add a white list of extensions which are allowed to be uploaded.
  # For images you might use something like this:
  def extension_white_list
     %w(jpg jpeg gif png)
  end

  # Override the filename of the uploaded files:
  # Avoid using model.id or version_name here, see uploader/store.rb for details.
  # def filename
  #   "something.jpg" if original_filename
  # end

end

In my user model i have: 在我的用户模型中,我有:

class User < ActiveRecord::Base
  mount_uploader :avatar, AvatarUploader
end

In my user controller - I whitelist the :avatar in strong params. 在我的用户控制器中 - 我将强化参数中的头像列入白名单。

In my profile controller strong params I've tried adding: 在我的个人资料控制器强大的params我试过添加:

params.require(:profile).permit(:title, :overview, user_attributes: [:avatar])

And I have also tried allowing user attributes in my profile model (as follows): 我还尝试在我的个人资料模型中允许用户属性(如下所示):

belongs_to :user
accepts_nested_attributes_for :user

I have a partial form in my views users folder. 我的视图用户文件夹中有一个部分表单。

<%= simple_fields_for :user,  html: { multipart: true } do |f| %>
  <%= f.error_notification %>
  <div class="form-inputs">
    <%= f.input :avatar, as: :file, :label => "Add a profile image (head shot)" %>
  </div>
<% end %>

That partial is included in my profiles form. 部分内容包含在我的个人资料表格中。

I then want to display the user avatar in my profile show view as: 然后我想在我的个人资料显示视图中显示用户头像:

<div class="col-md-5 col-lg-4 vc-photo" style= "background-image: url(<%= image_url @profile.user.avatar.url if @profile.user.avatar? %>);">&nbsp;</div>

However, it just renders a blank. 但是,它只是呈现一个空白。

I tried: 我试过了:

);"> );“>

but it still just renders blank. 但它仍然只是呈现空白。

Can anyone see what I've done wrong? 谁能看到我做错了什么?

When i try to test in the rails console by checking the user.avatar, I get this: 当我尝试通过检查user.avatar在rails控制台中测试时,我得到了这个:

u.avatar => #, last_sign_in_ip: #, confirmation_token: "73abb47df224dbc3a612b46ced66e1aba...", confirmed_at: "2016-04-02 07:13:57", confirmation_sent_at: "2016-04-02 22:59:44", unconfirmed_email: "testiest@gmail.com", failed_attempts: 0, unlock_token: nil, locked_at: nil, created_at: "2016-04-02 07:13:57", updated_at: "2016-04-02 22:59:43", avatar: nil, approved: false>, @mounted_as=:avatar> u.avatar =>#,last_sign_in_ip:#,confirmation_token:“73abb47df224dbc3a612b46ced66e1aba ...”,confirmed_at:“2016-04-02 07:13:57”,confirmation_sent_at:“2016-04-02 22:59:44”, unconfirmed_email:“testiest@gmail.com”,failed_attempts:0,unlock_token:nil,locked_at:nil,created_at:“2016-04-02 07:13:57”,updated_at:“2016-04-02 22:59:43 “,avatar:nil,approved:false>,@ mounted_as =:avatar>

TAKING THE SUGGESTION BELOW 采取以下建议

I change my forms so that profile form now has: 我更改了表单,以便配置文件表单现在具有:

<%= simple_fields_for :user,  html: { multipart: true } do |ff| %>
  <%= f.error_notification %>

              <div class="form-inputs">


              <%= ff.input :avatar, as: :file, :label => "Add a profile image (head shot)" %>

              </div>


        <% end %>

The users/profileimgform now has: users / profileimgform现在具有:

 <%= simple_fields_for :user, html: { multipart: true } do |ff| %> <%= f.error_notification %> <div class="form-inputs"> <%= ff.input :avatar, as: :file, :label => "Add a profile image (head shot)" %> </div> <% end %> 

I'm not sure whether I need to incorporate the 'ff' into the line in my profile form. 我不确定是否需要在我的个人资料表格中将'ff'纳入该行。 I tried replacing the last 'f' with 'ff' but got an error asking me whether it should be a single 'f'. 我尝试用'ff'替换最后的'f',但是错误地询问我是否应该是单个'f'。

When I try this, the console still shows that the user.avatar is 'nil'. 当我尝试这个时,控制台仍然显示user.avatar是'nil'。

I guess you have error with this code: 我猜这段代码有错误:

<%= simple_fields_for :user,  html: { multipart: true } do |f| %>
  <%= f.error_notification %>
  <div class="form-inputs">
    <%= f.input :avatar, as: :file, :label => "Add a profile image (head shot)" %>
  </div>
<% end %>

Look at html that is generated. 看看生成的html。 I think there should be something like this: 我认为应该是这样的:

<%= simple_form_for :profile do |f| %>
  ...
  <%= f.simple_fields_for :user do |ff| %>
    <%= ff.input :avatar %>
  <% end %>
<% end %>

Notice that nested form or complex form should connect model and association with form_for and fields_for helper, like this: 请注意,嵌套表单或复杂表单应该使用form_forfields_for helper连接模型和关联,如下所示:

<%= form_for @person do |f| %>
  Addresses:
  <ul>
    <%= f.fields_for :addresses do |addresses_form| %>
      <li>
        <%= addresses_form.label :kind %>
        <%= addresses_form.text_field :kind %>
      </li>
    <% end %>
  </ul>
<% end %>

The way to connect between model and associations is 模型和关联之间的连接方式是

  • form_for @person builds person form instance f form_for @person构建人员表单实例f
  • use person form instance f to build association form f.fields_for :addresses instance addresses_form 使用人物表格实例f来建立关联表格f.fields_for :addresses实例addresses_form f.fields_for :addresses形式
  • use association form input to upload file addresses_form.input ... 使用关联表单输入来上传文件addresses_form.input ...

Last, I guess simple_fields_for as extra helpers of simple_form, perhaps it only works for form_for helper. 最后,我想simple_fields_forsimple_fields_for 额外帮助者 ,也许它只适用于form_for帮助器。


Here is a example for given models and controllers: 以下是给定模型和控制器的示例:

app/models/user.rb 应用程序/模型/ user.rb

class User < ActiveRecord::Base
  mount_uploader :avatar, AvatarUploader
  has_one :profile
end

app/models/profile.rb 应用程序/模型/ profile.rb

class Profile < ActiveRecord::Base
  belongs_to :user
  accepts_nested_attributes_for :user
end

Actually, there's two ways to modify model's nested attributes. 实际上,有两种方法可以修改模型的嵌套属性。

  1. Modify the model and the nested attributes at the same form 以相同的形式修改模型和嵌套属性

You should build a complex form with both of your model and associations 您应该使用模型和关联构建复杂的表单

More info: http://guides.rubyonrails.org/form_helpers.html#building-complex-forms 更多信息: http//guides.rubyonrails.org/form_helpers.html#building-complex-forms

app/controllers/profile_controller.rb 应用程序/控制器/ profile_controller.rb

class ProfileController < ApplicationController

  private

  def profile_params
    params.require(:profile).permit(:title, user_attributes: [:avatar])
  end
end

app/views/profile/edit.html.erb 应用程序/视图/资料/ edit.html.erb

<%= form_for :profile do |f| %>
  Avatar:
  <ul>
    <%= f.fields_for :user do |uf| %>
      <li>
        <%= uf.label :avatar %>
        <%= uf.file_field :avatar %>
      </li>
    <% end %>
  </ul>
<% end %>
  1. Modify the nested attributes only 仅修改嵌套属性

You could build a normal form just for that association attribute, but it's tricky and vague when you have to initialize it, so I rather not to provide sample code here than confusing you. 你可以为那个关联属性构建一个普通的表单,但是当你必须初始化它时它很棘手和模糊,所以我宁愿不在这里提供示例代码而不是让你感到困惑。

我通过将头像从用户移动到个人资料来解决问题。

I had the same error. 我有同样的错误。 If you're on a mac, try installing imagemagik again. 如果你在Mac上,请尝试再次安装imagemagik。 I used homebrew. 我用的是自制软件。 You just need to run this command: 您只需要运行此命令:

brew install imagemagick

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

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