Question

I have a albums and images models. In my albums show.html.erb I have the following code:

<% @album.images.each do |image| %>

<p>
  <strong>name:</strong>
  <%= image.name %>
</p>

<p>
  <strong>url:</strong>
  <%= image.image_url(:thumb) %>
</p>

<%=  AlbumsHelper::Image.new({url:image.image_url(:thumb),
                             attributes:{title:image.name,
                                         description: image.description}
                            }).render.html_safe
%>

<% end %>

The AlbumsHelper::Image class render method simply renders html template. The issue is that the name and the url of each image are different, but the rendered html template is the same for all images.

I guess I am not instantiating in the correct way new objects from my AlbumsHelper::Image class. Could anyone tell what I am doing wrong?

EDIT:

  class Image

    IMAGE_NOT_FOUND = 'http://fuge.it/images/phoca_thumb_l_no_image.gif'
    THUMBNAIL_TEMPLATE = [
                          '<div class="view">',
                            '<div class="view-back">',
                              '<span data-icon="A">##title##</span>',
                              '<span data-icon="B">##description##</span>',
                              '<a href="##url##">→</a>',
                            '</div>',
                            '<div class="slice s1" style="background-image: url(##url##);">',
                              '<span class="overlay"></span>',
                              '<div class="slice s2" style="background-image: url(##url##);">',
                                '<span class="overlay"></span>',
                                '<div class="slice s3" style="background-image: url(##url##);">',
                                  '<span class="overlay"></span>',
                                  '<div class="slice s4" style="background-image: url(##url##);">',
                                    '<span class="overlay"></span>',
                                    '<div class="slice s5" style="background-image: url(##url##);">',
                                      '<span class="overlay"></span>',
                                    '</div>',
                                  '</div>',
                                  '</div>',
                                '</div>',
                            '</div>',
                          '</div>',
                          ].join('')

    attr_accessor :url,         # image source url
                  :attributes   # data attributes

    def initialize(parameters = {})
      @url = parameters.fetch(:url, IMAGE_NOT_FOUND)
      @attributes = parameters.fetch(:attributes, {})

      @url = IMAGE_NOT_FOUND unless File.extname(@url) =~/^(.png|.gif|.jpg)$/ #@url =~/^#{URI::regexp}$/ and
      @attributes = Hash.new unless @attributes.is_a?(Hash)
    end

    def to_s
      "<img src=#{@url} #{@attributes.map{|key,value| "data-#{key}=#{value}" }.join(' ')}/>"
    end

    def render(parameters = {})

      has_thumbnail = parameters.fetch(:has_thumbnail, 0)
      thumbnail_template = parameters.fetch(:thumbnail_template, THUMBNAIL_TEMPLATE)

      if has_thumbnail
        @attributes.map { |key, value| thumbnail_template["##{key}##"] &&= value }
        thumbnail_template.gsub!('##url##', @url)
        thumbnail_template
      else
        self.to_s
      end
    end


  end
Was it helpful?

Solution

thumbnail_template.gsub! changes your constant and replaces your placeholders with actual values. You can either add dup to copy the string

thumbnail_template = parameters.fetch(:thumbnail_template, THUMBNAIL_TEMPLATE).dup

or use gsub instead of gsub! and assign the returned value to a new variable.

You can also add .freeze to the constant to raise an error if the code tries to modify its value.

Also, why not render and .erb partial instead of manually manipulating string and reinventing the wheel?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top