【问题标题】:How can I reference images in the asset pipeline from a model?如何从模型中引用资产管道中的图像?
【发布时间】:2011-09-01 08:16:53
【问题描述】:

我有一个模型,它有一个方法可以将 url 返回到一个人的头像,如下所示:

 def avatar_url
   if self.avatar?
     self.avatar.url # This uses paperclip
   else
     "/images/avatars/none.png"
   end
 end

我正在升级到 3.1,所以现在需要通过资产管道引用硬编码的无图像。在控制器或视图中,我会将其包装在 image_path() 中,但我在模型中没有该选项。如何生成正确的图片网址?

【问题讨论】:

标签: ruby-on-rails ruby-on-rails-3 ruby-on-rails-3.1 asset-pipeline


【解决方案1】:

我在一段时间内一直在努力解决这个问题,所以我想我会在这里发布答案。虽然上述方法适用于标准默认图像(即每种回形针样式相同),但如果您需要多种默认样式,则需要不同的方法。

如果您想让默认 url 与资产管道和资产同步配合得很好,并且希望每种样式有不同的默认图像,那么您需要生成没有指纹的资产路径,否则您会收到很多 AssetNotPrecompiled 错误。

像这样:

   :default_url => ActionController::Base.helpers.asset_path("/missing/:style.png", :digest => false)

或在您的回形针选项中:

   :default_url => lambda { |a| "#{a.instance.create_default_url}" }

然后是模型中具有回形针附件的实例方法:

def create_default_url
   ActionController::Base.helpers.asset_path("/missing/:style.png", :digest => false)
end

在这种情况下,您仍然可以使用插值 (:style),但必须关闭资产指纹/摘要。

只要您同步没有摘要的资产以及有摘要的资产,这一切似乎都可以正常工作。

【讨论】:

  • Rails 4,回形针,不再需要。 :default_url => ":style/missing.jpg"。没有前导/
【解决方案2】:

就我个人而言,我认为您不应该将这个默认值放入模型中,因为它是一个视图细节。在您的(haml)视图中:

= image_tag(@image.avatar_url || 'none.png')

或者,创建您自己的助手并像这样使用它:

= avatar_or_default(@image)

当这样的事情在 Rails 中遇到困难时,通常表明它并不完全正确。

【讨论】:

  • 我经常在 json 中使用它(通过 as_json),这会取消该选项。
【解决方案3】:

我们使用 draper 解决了这个问题:https://github.com/jcasimir/draper。 Draper 让我们在模型周围添加一个包装器(用于视图中),它可以访问帮助器。

【讨论】:

  • 不错的建议。这颗宝石看起来很有前途。
  • 我相信 Draper 只是让使用与上面提到的@iain 相同的辅助方法变得更容易。引入 Draper 只是为了让您可以访问帮助程序是一种矫枉过正,但如果将其他逻辑移动到演示器中是有意义的,那么肯定 - 去吧。
【解决方案4】:

Paperclip 可以选择指定默认网址

has_attached_file :avatar, :default_url => '/images/.../missing_:style.png'

如果用户没有上传头像,你可以使用它来提供默认图片。

【讨论】:

  • 不幸的是,default_url 参数也没有通过资产管道助手处理。
  • 你可以做:default_url => ActionController::Base.helpers.image_path("/default_avatar.png")
【解决方案5】:

使用 rails active storage 我解决了这个问题:

# Post.rb
def Post < ApplicationRecord
    has_one_attached :image

    def thumbnail
        self.image.attached? ? self.image.variant(resize: "150x150").processed.service_url : 'placeholder.png';
    end

    def medium
        self.image.attached? ? self.image.variant(resize: "300x300").processed.service_url : 'placeholder.png';
    end

    def large
        self.image.attached? ? self.image.variant(resize: "600x600").processed.service_url : 'placeholder.png';
    end
end

那么在您看来,只需调用: &lt;%= image_tag @post.thumbnail %&gt;,

【讨论】:

    猜你喜欢
    • 2019-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-10
    • 1970-01-01
    相关资源
    最近更新 更多