69

I have a rake task to seed an application with random data using the faker gem. However, we also have images (like logos) that we want uploaded in this rake task.

We already have Paperclip set up, but don't have a way to upload them programmatically in a rake task. Any ideas?

Jaryl
  • 2,561
  • 1
  • 24
  • 33

3 Answers3

145

What do you mean by programmatically? You can set up a method that will take a file path along the lines of

my_model_instance = MyModel.new
file = File.open(file_path)
my_model_instance.attachment = file
file.close
my_model_instance.save!

#attachment comes from our Paperclip declaration in our model. In this case, our model looks like

class MyModel < ActiveRecord::Base
  has_attached_file :attachment
end

We've done things similar to this when bootstrapping a project.

clyfe
  • 23,695
  • 8
  • 85
  • 109
theIV
  • 25,434
  • 5
  • 54
  • 58
  • 5
    `attachment` is whatever you have set in `has_attached_file :attachment,` – B Seven Dec 04 '12 at 05:03
  • 1
    @BSeven do you think it would be clearer if I added that to the answer? If so, I'll add it. – theIV Dec 04 '12 at 16:06
  • Yes. It's not clear if `attachment` is a reserved word or user defined. – B Seven Dec 04 '12 at 16:08
  • 2
    Please stop preaching open file and forget, it's such a nasty thing in the ruby community. .open and then .close or use a block. – clyfe Mar 08 '13 at 22:03
  • 3
    @clyfe you are more than welcome to make an edit to the post. If you won't, which of the two methods (`#close` or block) do you prefer? Also, preaching is a bit strong, no? However, you're point is well received. – theIV Mar 08 '13 at 23:22
12

I do something like this in a rake task.

photo_path = './test/fixtures/files/*.jpg'
Dir.glob(photo_path).entries.each do |e|
  model = Model.find(<query here>)        
  model.attachment = File.open(e)
  model.save
end

I hope this helps!

Puce
  • 1,003
  • 14
  • 28
jonnii
  • 28,019
  • 8
  • 80
  • 108
8

I didn't actually have to write a method for this. Much simpler.

In Model ->

Class Model_Name < ActiveRecord::Base
  has_attached_file :my_attachment,
  :params_for_attachment

In seed.db ->

my_instance = Model_name.new
my_instance.my_attachment = File.open('path/to/file/relative/to/app')
my_instance.save!

Perhaps the previous answers meant to use the name of the attachment as defined in the model (rather than writing a method Model_name.attachment). Hope this is clear.

winfred
  • 81
  • 1
  • 2
  • or in one line `my_instance = Model_name.create!(my_attachment: File.open('path/to/file/relative/to/app'))` – scarver2 Jun 30 '14 at 13:33
  • fyi for some reason i couldn't get the multiline to work but scarver2's one worked a treat – Ben Dec 12 '14 at 06:08