从附件中为 :url 定义液体方法的位置

Where to define liquid method for :url from attached file

我博客的帖子有几张图片

class Post < ActiveRecord::Base
     has_many :pictures, dependent: :destroy
end

图片有附加的图片文件,我用gem回形针来处理这个。

class Picture < ActiveRecord::Base
    belongs_to :post

    has_attached_file :image,
        :path => ":rails_root/public/images/:id/:filename",
        :url  => "/images/:id/:filename",
        styles: { medium: "300x300>", thumb: "100x100>"  } 

    do_not_validate_attachment_file_type :image
end

我可以使用 <%= image_tag picture.image.url %> 轻松创建图片标签 所以 picture.image.url returns 存储图像的 url 。我正在尝试通过液体模板 gem 获得此 url。 我想做类似

的事情
{% for picture in pictures %} 
<li style="background-image:'{{picture.image.url(:medium)}}';"></li>  
{% endfor %} 

我猜我需要一个液体方法 :url,但我没有模型来编写它(因为 image 是一个附件,而不是模型)。有人知道我如何通过液体获得图像 url 吗?

似乎最简单的方法是手动序列化您的图片:

# ruby code
Liquid::Template.parse(text).render("pictures" => @post.pictures.map{|p| {'id' => p.id, 'medium_image_url' => p.image.url(:medium)})

# liquid code
{% for picture in pictures %} 
  <li style="background-image:'{{picture.medium_image_url}}';"></li>  
{% endfor %}

如果要将序列化分离到单独的模块中,可以将其移动到ActiveModel::Serializer or Liquid::Drop。如果您还使用 JSON(或 XML)序列化,ActiveModel::Serializer 是一个不错的决定,否则 Liquid::Drop 是更可取的选择(它专门用于序列化为 liquid)。这是来自 Liquid::Drop 文档的修改示例:

# Ruby code

class PictureDrop < Liquid::Drop
  def initialize(picture)
    @picture = picture
  end

  def id
    @picture["id"]
  end

  def image_urls
    {
      'medium' => @picture.image.url(:medium),
      'thumb' => @picture.image.url(:thumb)
    }
  end
end

markdown = Liquid::Template.parse(text).render("pictures" => @post.pictures.map{|p| PictureDrop.new(p)})

# liquid code

{% for picture in pictures %} 
    <li style="background-image:'{{picture.image_urls['medium']}}';"></li>  
{% endfor %}