19

I am currently trying to populate a development database on a project with a bunch of fake data, to simulate how it will look and operate with hundreds of articles / users. I looked into different gems to do the task - such as Factory Girl, but documentation was very lacking and I didn't get it - but ended up using the Populator and Faker gems and did the following rake task...

namespace :db do
   desc "Testing populator"
   task :populate => :environment do
      require "populator"
      require "faker"

      User.populate 3 do |user|
         name = Faker::Internet.user_name   
         user.name = name
         user.cached_slug = name
         user.email = Faker::Internet.email
         user.created_at = 4.years.ago..Time.now
      end
   end
end

Works great...for text based data. However, all users have an avatar that can be uploaded via Paperclip attachment, as well as all regular content have thumbnail attachments in the same manner.

I understand the Populator gem simply does a straight population to the database and not necessarily running through ActiveRecord validations to do so..therefor I would assume Paperclip can't run to generate all the different thumbnails and needed (and uploaded to the proper directory) for the avatar if I just filled the field with a filepath in the rake task above.

Is there a way to populate fake images, via Populator or another way? Or perhaps a way to point the rake task at a directory of stock images on my hard drive to autogenerate random thumbnails for each record? Took a hunt on Google for a way, but have not turned up much information on the subject.

UPDATE

The final solution, based on pwnfactory's line of thinking...

namespace :db do
  desc "Testing populator"
  task :populate => :environment do
    require "populator"
    require "faker"

    User.populate 3 do |user|
      name = Faker::Internet.user_name
      user.name = name
      user.cached_slug = name
      user.email = Faker::Internet.email
      user.created_at = 4.years.ago..Time.now
    end

    User.all.each { |user| user.avatar = File.open(Dir.glob(File.join(Rails.root, 'sampleimages', '*')).sample); user.save! }
  end
end

It basically loops back around and uploaded avatars from the sampleimages directory on all the records.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Shannon
  • 2,744
  • 3
  • 28
  • 37

3 Answers3

7

To associate a random image in your task, you could try the following:

user.avatar = File.open(Dir.glob(File.join(Rails.root, 'sampleimages', '*')).sample)

where sampleimages is a directory containing avatars to be associated at random

acw
  • 1,093
  • 10
  • 14
  • Gave this a try and inserted that line in my rake task above (and created the sampleimages directory in my rails project proper) but it spit out "rake aborted! undefined method `avatar=' for #" on running the task. Since the database splits the columns into three (avatar_file_name, avatar_content_type, avatar_file_size), that might be why. – Shannon Apr 26 '11 at 15:41
  • You must use the name you defined in your model, for example: `class Photo < ActiveRecord::Base has_attached_file :foto end` Here, you'd want to use photo.foto = ... – acw Apr 26 '11 at 15:46
  • That is what I'm doing, the attachment to my User model is named 'avatar' (has_attached_file :avatar). – Shannon Apr 26 '11 at 15:56
  • Sorry, didn't realize that Populate doesn't use actual instances of the model. One idea would be a second loop using the AR instances to set the avatars. For example: `User.all.each{ |user| user.avatar = File.open(Dir.glob(File.join(Rails.root, 'sampleimages', '*')).sample);user.save}` although this may somewhat defeat the purpose of Populate – acw Apr 26 '11 at 16:03
  • Right, a bit rigged, but it works. I had to make a slight tweak to your code (pasted the revised version above), but basically after generating the users via Populate, it loops back around and uploads avatars to each one. Only downer is that I think it overwrites those who already have avatars uploaded, but it should be very simple from here to work in conditions to target only NULL users. Thank you much. – Shannon Apr 26 '11 at 16:31
1
user.avatar = File.open(Dir['app/assets/images/*.jpg'].sample)
Mikhail Chuprynski
  • 2,404
  • 2
  • 29
  • 42
0

One way I get around this is to put a conditional in my views.

Let's say your model is "user", and it has an avatar. Then you can do the following:

<% if product.avatar.exists? %>
  ... show the attached photo
<% else %>
  .. show a default photo
<% end %>

This works for me with Paperclip, and I use it in my dev database all the time rather than worrying about having all the image attached to all the users.

jefflunt
  • 33,527
  • 7
  • 88
  • 126
  • 2
    Off-topic, but there is another way to do that...if you use a default_url in your has_attached_file in your model, the paperclip call in your views will fall back to the default image if no uploaded image is found. Handy and reduces view code. As for my situation, I already have my users set up that way, but I want to see some randomness...not to mention content HAS to have a image attached, there is no fallback version. – Shannon Apr 26 '11 at 15:33