【问题标题】:Fallback Image with Carrierwave使用载波的后备图像
【发布时间】:2014-05-21 16:27:15
【问题描述】:

除了一件小事之外,我的上传器运行良好。默认图像的设置。我正在使用carrierwave让用户上传自己的个人资料图片:

用户模型

class User < ActiveRecord::Base     
    has_one :avatar, class_name: 'Image', foreign_key: :user_id

    before_create :create_fallback_image

    def create_fallback_image
        self.create_avatar
    end
end

图像模型

class Image < ActiveRecord::Base

    mount_uploader :file_name, AvatarUploader, auto_validate: false

    belongs_to :user
end

头像上传器

class AvatarUploader < BaseUploader

  include CarrierWave::RMagick

  storage :file

  process resize_to_fit: [75, 75]
  process convert: 'gif'

  def default_url
   'foobar'
  end

  def filename
      random_string + '.gif'
    end
  end

  def random_string
    @random_string ||= User.random_string
  end
end

当用户在没有上传可选的个人资料图片的情况下注册时,他们会被分配到他们的个人资料图片的关联,但default_url 不会起作用,他们会从文件名方法中获得一个随机字符串。

我想我可以这样解决它:

用户模型

class User < ActiveRecord::Base     
    has_one :avatar, class_name: 'Image', foreign_key: :user_id

    before_create :create_fallback_image

    def create_fallback_image
            # look here:

        self.create_avatar.create_fallback
    end
end

图像模型

class Image < ActiveRecord::Base

    mount_uploader :file_name, AvatarUploader, auto_validate: false

    belongs_to :user

    def create_fallback
       self.update_attributes(file_name: 'my_fallback.jpg')
    end
end

虽然它几乎,几乎可以正常工作,但当我更新 file_name 列的属性时,上传程序启动,my_fallback.jpg 被我的random_string 方法中的随机字符串覆盖!

【问题讨论】:

  • 根据聊天讨论,我已经用辅助方法更新了我的答案。

标签: ruby-on-rails carrierwave


【解决方案1】:

Carrierwave 具有内置的默认图像回退机制

如下更新AvatarUploader 中的default_url 方法:

  def default_url
    ActionController::Base.helpers.asset_path("fallback/" + [version_name, "my_fallback.jpg"].compact.join('_'))
  end

将fallback/ 更改为您想要的文件夹路径。 这样,当没有为特定用户上传 avatar 时,my_fallback.jpg 将用作备用图片。

请参阅 Carrierwave 文档中的 Providing a default URL 部分。

当我更新 file_name 列的属性时,上传者 开始,my_fallback.jpg 被我的随机字符串覆盖 random_string 方法!

发生这种情况是因为您在 AvatarUploader 中覆盖了 filename 方法,每次上传图片时都会调用该方法。如果您注意到,它在其中调用 random_string 方法。因此,您将获得 random string 作为文件名。

更新

根据与 OP 的聊天会话,如果未为用户上传头像,则应显示默认图像。我建议了以下助手:

module ApplicationHelper
  def display_avatar(user)  
    unless user.avatar.nil? 
      image_tag(user.avatar.file_name) 
    else
      image_tag("/path/to/fallback.jpg")
     end    
  end
  ## ...
end

在视图中使用此辅助方法以适当地显示头像图像。

【讨论】:

  • 所以这应该可以工作,即使default_url 没有返回"foobar"?
  • 我的意思是你应该使用可用的回退机制而不是创建一个新的。在您的情况下,default_url 不会被调用,因为您正在使用随机字符串手动更新 file_name。当file_name 未设置时,default_url 将出现在图片中,即它的 nil。
  • 我用你给我的助手替换了我的 default_url,但我仍然通过我的 file_name 方法获取随机字符串。这是因为正在数据库中创建一个新头像,并且carrierwave 认为必须也上传了一个新图像我猜......我认为这里的罪魁祸首是我在模型中的self.create_avatar 调用,但我还能做什么?用户需要一个头像,即使它是后备。否则我无法在视图中运行&lt;%= image_tag user.avatar.file_name %&gt;...
  • 底线是您不需要更新没有任何图像的记录。因为它会被 default_url 照顾。
  • 好的.. 但是如果某些用户没有头像,我应该如何在视图中运行&lt;%= image_tag user.avatar.file_name %&gt;?在用户模型中创建虚拟属性?
【解决方案2】:

此外,您可以在模型中执行此操作:

class User < ApplicationRecord
  has_one :avatar, class_name: 'User::Avatar', as: :parent, dependent: :destroy
  accepts_nested_attributes_for :avatar, allow_destroy: true #, ...

  def avatar
    super || build_avatar
  end
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-08
    • 2013-05-01
    • 2016-03-01
    • 2013-03-30
    • 1970-01-01
    • 2020-04-30
    • 1970-01-01
    • 2018-07-27
    相关资源
    最近更新 更多