使用Ruby on Rails Populator / Faker Gems生成带有虚假数据的Paperclip图像上传。

19

我目前正在尝试为一个项目填充开发数据库,用大量虚假数据模拟它在有数百篇文章/用户的情况下的外观和操作。我研究了不同的gems来完成这个任务 - 比如Factory Girl,但是文档非常缺乏,我不理解 - 但最终使用了Populator和Faker gems,并执行了以下Rake任务...

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

对于基于文本的数据,它非常有效。但是,所有用户都有一个头像,可以通过Paperclip附件上传,所有常规内容也以同样的方式具有缩略图附件。

我了解Populator gem只是直接向数据库填充数据,不一定要运行ActiveRecord验证来完成此操作。因此,如果我只是填写了文件路径,就不能使用Paperclip来生成所有不同的缩略图并将其上传到正确的目录。

是否有一种方法可以通过Populator或其他方式生成虚假图片?或者,是否有一种将rake任务指向硬盘上的库存图片目录以为每条记录自动生成随机缩略图的方法?我在Google上搜寻了一番,但并没有找到太多相关信息。

更新

根据pwnfactory的思路,最终解决方案如下...

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

基本上,它会在所有记录中循环回来,并从sampleimages目录上传头像。

3个回答

7

如果您想在任务中关联一张随机图片,可以尝试以下方法:

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

其中sampleimages是一个包含随机关联的头像的目录


尝试了一下,在我的rake任务中插入了那行代码(并在我的rails项目中创建了sampleimages目录),但运行任务时它报错了:“rake aborted!undefined method `avatar=' for #Populator::Record:0x103fed130”。由于数据库将列分成三个部分(avatar_file_name,avatar_content_type,avatar_file_size),这可能是原因。 - Shannon
你必须使用在模型中定义的名称,例如:class Photo < ActiveRecord::Base has_attached_file :foto end在这里,你需要使用 photo.foto = ... - acw
这就是我正在做的,我的用户模型附加的文件名为“avatar”(has_attached_file:avatar)。 - Shannon
抱歉,没有意识到 Populate 不使用模型的实际实例。一个想法是使用 AR 实例设置头像的第二个循环。例如:User.all.each{ |user| user.avatar = File.open(Dir.glob(File.join(Rails.root, 'sampleimages', '*')).sample);user.save}虽然这可能有点违背 Populate 的目的。 - acw
没错,有点偷懒,但它能用。我对你的代码进行了微调(已经复制粘贴了修订版),但基本上是通过使用 Populate 生成用户,然后循环回来并为每个用户上传头像。唯一的缺点是我认为它会覆盖那些已经上传了头像的用户,但从这里开始,应该很容易加入条件以仅针对 NULL 用户。非常感谢。 - Shannon

1
user.avatar = File.open(Dir['app/assets/images/*.jpg'].sample)

0

我解决这个问题的一种方法是在我的视图中加入一个条件语句。

假设你的模型是“用户”,并且它有一个头像。那么你可以这样做:

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

这对我来说使用Paperclip很有效,我在开发数据库中经常使用它,而不必担心所有图像都附加到所有用户上。


2
离题了,但是还有另一种方法可以做到这一点...如果你在模型中使用has_attached_file的default_url,那么视图中的paperclip调用将会在没有上传图片的情况下回退到默认图片。非常方便,减少了视图代码。至于我的情况,我已经按照这种方式设置了我的用户,但我想看到一些随机性...更不用说内容必须附带图片,没有备用版本。 - Shannon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接