views:

1541

answers:

4

I'm handling file attachments in my Rails app with Attachment_fu, which provides a public_filename method to retrieve a file's URL. I'm using it on a model called Cover, so if I want to call the URL of an uploaded cover image, in a view I would do:

<%= image_tag(@cover.public_filename) %>

This works just fine when the user has the appropriate attachment, but in my application it is not a requirement for a user to upload an attachment.

Therefore, calling @cover.public_filename will throw a TypeError: Can't convert nil into String for the obvious reason that the file is nil.

However, I'm having trouble adding logic to this problem effectively since the object is nil, and all of my attempts with doing things like unless @cover.public_filename.nil? or if @cover.public_filename == nil have been fruitless and cause the same Type Error.

What am I missing?

+1  A: 
<%= image_tag(@cover.public_filename) unless @cover.nil? %>

Sorry, can't comment, so here's an update instead:

@cover.public_filename? won't work here because @cover is a nil object and as such has no public_filename? method.

nil.respond_to?('public_filename?') #=> false
xyz
Thanks for the update. This makes total sense with @cover being nil and @cover.class => NilClass in this case. I'm still getting a TypeError the moment @cover.public_filename is processed using <%= image_tag(@cover.public_filename) unless @cover.nil %> though, and can't seem to figure out why.
Bryan Woods
Is that a typo? It should be `unless @cover.nil?` (note the question mark) and not `unless @cover.nil`.
xyz
Yes, typo. My apologies. <%= image_tag(@cover.public_filename) unless @cover.nil? %> Had no effect on solving the Type Error in this case, unfortunately. It looks like the error is caused when @cover.public_filename gets processed either way.
Bryan Woods
It should work (just tested it in my console). Are you sure you're looking at the right code? Maybe there is another instance of image_tag(@cover.public_filename) elsewhere? And did you try restarting the server (apache/webrick/thin/whatever)?
xyz
So strange. I've restarted the server and can't find another instance. The stack trace looks like it's generating from attachment_fu/backends/s3_backend.rb (I'm using the S3 backend in Attachment_fu). I can't imagine this could be a bug in the plugin, but I'm at a loss as to where else this could be coming from.
Bryan Woods
I have no more ideas. Not quite the answer you might hope for, but maybe you could try #rubyonrails on irc.freenode.org. Or maybe even try moving away from attachment_fu. Paperclip shold work with S3 just fine.
xyz
A: 

Updated:

Make it:

<%= image_tag(@cover.public_filename) if @cover && @cover.public_filename? %>

Chuck
This is along the lines of what I was expecting, but is returning a NoMethodError (undefined method `public_filename?'). Does this make sense?
Bryan Woods
I'm looking into sources of attachment_fu and I don't see method public_filename? . Or am I wrong?
klew
public_filename? doesn't seem to work.
Bryan Woods
+1  A: 

I didn't work with attachment_fu, but as I see public_filename is method that relies on some fields that are nil when you don't have attachment attached. Here I read that attachment_fu should always has attachment - and this is probably a reason why it didn't work for you. The author also suggest using paperclip plugin. Take a look at it!

klew
Well I'll be. Thanks for the tip.
Bryan Woods