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 %>
Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Apr 29, 2012 at 18:24
\$\endgroup\$
1
  • 1
    \$\begingroup\$ write a helper that returns a string given a filetype (isJPG, isPNG, ...). \$\endgroup\$ Commented Apr 29, 2012 at 18:26

2 Answers 2

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 %>
answered Apr 29, 2012 at 18:58
\$\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:

answered May 2, 2012 at 17:01
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.