views:

10

answers:

1

Hi, I'm creating an application that'll display a random picture based upon a defined letter in a word.

Images are attached to a Pictures model (containing another "letter" field) using Paperclip, and will be iterated through in an each block.

How would I go about passing the letter back from the each block to the model for random selection.

This is what I've come up with so far, but it's throwing the following error.

 undefined method `%' for {:letter=>"e"}:Hash

Model:

def self.random(letter)
  if (c = count) != 0
    find(:first, :conditions => [:letter => letter], :offset =>rand(c))
  end
end

View:

<% @letters.each do |a| %>
    <%= Picture.random(a).image(:thumb) %>
<% end %>

Thanks

+1  A: 

One problem is your conditions has a syntax error. The hash notation is wrong:

:conditions => [:letter => letter]

should be

:conditions => {:letter => letter}

Also, it seems to me that your random scope will always exclude the first Picture if you don't allow an offset of 0. Besides that, do you really want to return nil if the random number was 0?

Picture.random(a).image(:thumb) would throw "undefined method 'image' for nil:NilClass" exception every time c==0. Can probably just use:

def self.random(letter)
  find(:first, :conditions => {:letter => letter}, :offset =>rand(count))
end

EDIT: You'll either need to guarantee that your db has images for all letters, or tell the user no image exists for a given letter.

<% @letters.each do |a| %>
  <% if pic = Picture.random(a).image(:thumb) %>
    <%= pic.image(:thumb) %>
  <% else %>
    No image available for <%= a %>
  <% end %>
<% end %>

Or the like...

EDIT: Actually I don't think your offset strategy will work. One other approach would be to return the set of images available for the given letter and randomly select from that collection, something like:

def self.random(letter)
  pics = find(:all, :conditions => {:letter => letter})
  pics[rand(pics.size)] if !pics.blank?
end
Dave Sims
Hmm, yes it does throw an "undefined method 'image' for nil:NilClass", it also does when removing the reference to not being 0.
Steve F
Make sure your DB is seeded with images for the letters you might encounter. If the image for 'letter' isn't in the db, you'll get the nil error. Or you need to gracefully fail for the user (see edit).
Dave Sims
Thanks! It does still fail with any offset though.
Steve F
Yeah, offset's not gonna work. (see new edit)
Dave Sims
The new solution works fantastically! Thanks for all your help!
Steve F