0

I am using Paperclip for image upload in a Rails 3.2 app. The goal is to show users every time they create a new post, a different (randomly changing) default image, before they upload their own image.

I found this and this questions here, but unfortunately the solutions don't work for me.

This is the post.rb model:

has_attached_file :image, styles: { medium: "320x240>"}
validates_attachment :image, 
content_type: { content_type: ['image/jpeg', 'image/jpg', 'image/png'] }, 
size: { less_than: 2.megabytes }

belongs_to :user
has_attached_file :image, styles: { thumb: "100x100", small: "160x120", medium: "320x240>", large: "640x480", fullscreen: "1000x300#" },
:default_url => '/assets/1.jpg'

Instead of :default_url => '/assets/1.jpg' I would like to set something that shows randomly one of the ten images (1.jpg to 10.jpg).

If I try to use :default_url => lambda {'/assets/#{rand(5)}.jpg'} I get this Error: ArgumentError in Posts#new - wrong number of arguments (1 for 0)

Community
  • 1
  • 1
YvonC
  • 329
  • 2
  • 6
  • 22

1 Answers1

2

The problem is that to do what you want, paperclip must support lambdas in default_url.
Considering I think it doesn't (but I'm not sure, I read something about it a lot of time ago), I suggest you to take the "easy route" even if it feels less correct (but not that much). With a view and a helper, do something like this:

post_helper.rb

module PostHelper

  def post_image_url(post)
    return post.image.url if post.image.exists?

    number_between_0_and_3 = rand(4)

    "my_random_image_#{ number_between_0_and_3 }.jpg"
  end

end

my_view.html.erb

<%= image_tag(post_image_url(@post), alt: 'Dunno') %>

If you have in your app/assets/images these 4 files:

  • my_random_image_0.jpg
  • my_random_image_1.jpg
  • my_random_image_2.jpg
  • my_random_image_3.jpg

One of those will be randomly selected every time.

Important notice: I didn't test the code so you may find some minor bugs but the idea and if you consider it as pseudocode, is ok. I'm quite sure it will work anyway.

Important notice 2: This will change the user image every time you visit the page.

If you want to create a random image that is permanent for the user across pages, you may want to have this approach: based on user id (which is "random" more or less), you can simply replace your helper with this:

post_helper.rb

module PostHelper

  def post_image_url(post)
    return post.image.url if post.image.exists?

    # Here is the change, you must ensure post.user is always present anyway!
    number_between_0_and_3 = post.user.id % 4

    "my_random_image_#{ number_between_0_and_3 }.jpg"
  end

end

This will grant user a random image between my_random_image_0.jpg and my_random_image_3.jpg based on id, so it won't change across pages but it will still be pseudo random.

Also you have the advantage that if the user check his profile, the avatar image will result empty instead of having an image displayed there (so the user knows he must add an avatar, better user experience).

Francesco Belladonna
  • 11,361
  • 12
  • 77
  • 147
  • Thank you so much for your fast reply! You made a suggestion for a "view.html.erb" - but what to do I write in the post.rb model instead of the :default_url => '/assets/1.jpg' ? Can I delete it? – YvonC Jan 21 '14 at 18:02
  • @YvonC: You can do both, I suggest you to always have a default url so keep it, even if you don't use it at all. Also please see my edit which has some improvements – Francesco Belladonna Jan 21 '14 at 18:05
  • Thanks @Fire-Dragon-DoL; this solution was perfect. To anyone else, if you're working with different image sizes, simply add another parameter to the helper method: image_tag(post_image_url(post, 'medium')). – onichase Aug 29 '14 at 00:50