Seeding file uploads with CarrierWave, Rails 3

2019-01-31 12:18发布

问题:

I'm trying to seed a database in Rails 3 with images using CarrierWave, however nothing I try seems to work short of having to upload them all by hand.

pi = ProductImage.new(:product => product)
pi.image = File.open(File.join(Rails.root, 'test.jpg'))
pi.store_image! # tried with and without this
product.product_images << pi
product.save!

Anybody know how to seed using CarrierWave at all?

回答1:

Turns out the documentation for CarrierWave is slightly wrong. There is a more up to date piece of code in the README at the GitHub repository for the project.

In a nutshell, though:

pi = ProductImage.create!(:product => product)
pi.image.store!(File.open(File.join(Rails.root, 'test.jpg')))
product.product_images << pi
product.save!


回答2:

So long as your uploader is mounted to your model, using the mount_uploader method, you can seed your models with carrierwave using the relevant open method. This would be a more concise way of achieving the same thing. In my case I'm seeding from a URL:

Game.create([
{
  :title => "Title",
  :uuid_old => "1e5e5822-28a1-11e0-91fa-0800200c9a66", 
  :link_href => "link_href", 
  :icon => open("http://feed.namespace.com/icon/lcgol.png"),
  :updated_at => "2011-01-25 16:38:46", 
  :platforms => Platform.where("name = 'iPhone'"), 
  :summary => "Blah, blah, blah...", 
  :feed_position => 0, 
  :languages => Language.where("code = 'de'"), 
  :tags => Tag.where(:name => ['LCGOL', 'TR', 'action'])
},
{...


回答3:

Here's an example script I incorporated into a seed.rb file for one of my projects. I'm sure it can be improved but it provides a good working example.

All the assets I'm pulling are stored within the app/assets/images and they have names matching the names of my Info objects (after I replace spaces with underscores and downcase the names).

Yes it does sound inefficient, but apart from putting those assets on an FTP somehwhere, it's the best solution I found for my remote server to be able to upload the files straight to S3 using Carrierwave and Fog.

My Info model has a has_one association to a Gallery model, which has a has_many association to a Photo model. The Carrierwave uploader is mounted on the 'file' (string) column of that model.

Info.all.each do |info|              
  info_name = info.name.downcase.gsub(' ', '_')
  directory = File.join(Rails.root, "app/assets/images/infos/stock/#{info_name}")

  # making sure the directory for this service exists
  if File.directory?(directory)
    gallery = info.create_gallery

    Dir.foreach(directory) do |item|
      next if item == '.' or item == '..'
      # do work on real items
      image = Photo.create!(gallery_id: gallery.id)
      image.file.store!(File.open(File.join(directory, item)))
      gallery.photos << image
    end

    info.save!

  end
end

This works flawlessly for me, but ideally I wouldn't have to package the files that I'm uploading to S3 within the assets folder. I'm more than open to suggestions & improvements.



回答4:

It's all in the documentation: https://github.com/carrierwaveuploader/carrierwave/wiki/How-to:-%22Upload%22-from-a-local-file

restaurant = Restaurant.create!(name: "McDonald's")
restaurant.logo = Rails.root.join("db/images/mcdonalds_logo.png").open
restaurant.save!


回答5:

Building on @joseph jaber's comment this worked a treat for me:

The code below shoud be in seeds.rb

20.times do
        User.create!(
            name: "John Smith",
            email: "john@gmail.com",
            remote_avatar_url: (Faker::Avatar.image)
        )
    end

This will create 20 users and give each one a different avatar image.

I have used the faker gem to generate the data but all Faker::Avatar.image does is return a standard url, so you could use any url of your choice.

The above example assumes that the User models attribute where you store you images is called avatar

If the attribute was called image you would write like this:

remote_image_url: (Faker::Avatar.image)



回答6:

The easiest solution for me was:

  1. Comment-out the mount_uploader line in the model
  2. Seed the data
  3. Uncomment the line in the model