2
\$\begingroup\$

This allows users to upload an file from the browser into my Rails app using the paperclip gem. Once the file is uploaded it gets saved into the filesystem. When the user then goes in and the "show" method or the "edit" method is evoked the image is shown to the user. This is fine for image files but for .csv and .txt files I don't want to show the preview in the browser. This code is clunky and I know there is a better way to do this.

<% if @user.image? %>
<%=filetype = @user.image.url %><br/>
<%if filetype.include? ".jpeg" %>
    <b>isJpeg</b>
    <%= image_tag @user.image.url %> <br />
    <%= link_to @user.image.url, @user.image.url  %>
<% end %> 
<%if filetype.include? ".gif" %>
    <b>isGif</b>
    <%= image_tag @user.image.url %> <br />
    <%= link_to @user.image.url, @user.image.url  %>
<% end %>
<%if filetype.include? ".png" %>
    <b>isPNG</b>
    <%= image_tag @user.image.url %> <br />
    <%= link_to @user.image.url, @user.image.url  %>
<% end %>
<%if filetype.include? ".jpg" %>
    <b>isJPG</b>
    <%= image_tag @user.image.url %> <br />
    <%= link_to @user.image.url, @user.image.url  %>
<% end %>
<%if filetype.include? ".csv" %>
    <b>isCSV</b>
    <p>Your file was a csv file and has no preview</p>
    <%= link_to @user.image.url, @user.image.url  %>
<% end %>

<%= image_tag @user.image.url %> <br />
<%= link_to @user.image.url, @user.image.url  %>
<% end %>
\$\endgroup\$
  • 1
    \$\begingroup\$ write a helper that returns a string given a filetype (isJPG, isPNG, ...). \$\endgroup\$ – tokland Apr 29 '12 at 18:26
2
\$\begingroup\$

tokland is right (on both counts), you should push all that logic into a helper. You can also add a bit of OpenStruct into the mix to make the helper nicer:

# in app/helpers/application_helper.rb or another helper
def user_image_info(user)
    info = OpenStruct.new(:has_image? => false)
    return info if(!user.image?)

    # There might be better ways to do this but I don't know paperclip.
    u = user.image.url
    %w[jpeg gif png jpg csv].find do |ext|
        # A small abuse of `find` but reasonable in this case.
        info.is = "is#{ext.upcase}" if(u.include?(".#{ext}"))
    end
    if(info.is == 'isCSV')
        info.preview_link = '<p>Your file was a csv file and has no preview</p>'.html_safe
    else
        info.preview_link = (image_tag(user.image.url) + '<br>').html_safe
    end
    info
end

Then in your ERB, you could do something like this:

<% info = user_image_info(@user) %>
<% if info.has_image? %>
    <b><%= info.is %></b>
    <%= info.preview_link %>
    <%= link_to @user.image.url, @user.image.url  %>
<% end %>
|improve this answer|||||
\$\endgroup\$
1
\$\begingroup\$

I'd use some kind of presenter here. Or exhibit (see Objects on Rails). So some object where you can extract your view logic.

# replace you view with these 2 lines of code
<% @user = UserExhibit.new(user, view) %>
<%= @user.render %>



class UserExhibit < SimpleDelegator
  def initialize(user, context)
    @context = context
    super(user)
  end

  def render
    return '' unless @user.image?
    @context.render partial: "user_image", locals: { user: self }
  end

  def filetype
    image.url
  end

  def image_is_picture?
    filetype =~ /\.(jpeg|gif|png|jpg)$/
  end

  def image_type
    filetype[/\.(\w+)$/, 1]
  end
end


# _user_image.html.erb partial
<b>is<%= @user.image_type.upcase %></b>

<%if @user.image_is_picture? %>
    <%= image_tag @user.image.url %> <br/>
    <%= link_to @user.image.url, @user.image.url  %>
<% else %>
    <p>Your file was a <%= @user.image_type %> file and has no preview</p>
    <%= link_to @user.image.url, @user.image.url  %>
<% end %> 

<%= image_tag @user.image.url %> <br/>
<%= link_to @user.image.url, @user.image.url  %>

Also, you may find useful these links:

|improve this answer|||||
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy