Assigning default avatars (batch upload for 30k records)


I have read the docs and am not entirely sure what the suggested approach is for:

  1. I have 28 avatars
  2. I want to assign everyone (~30k users) one of these avatars randomly
  3. I want this to be as simple as possible (i.e. I could assign everyone one of these 28; then 30k background jobs are kicked off … and I end up with 30k + 28 files; I would rather just have a 30k pointers and a total of 28 files).

Is this possible (and I don’t want the avatars in a separate table — it has to be a avatar_data field on the users table)?

Assuming you are uploading the files into the same directory (default filesystem approach, also default for cloud storage), you could upload one each of the 28, then randomly duplicate the avatar_data column value into the other 30K. It would not be exactly the way that Shrine would do it left to its defaults, but it would definitely ensure that you only have one each of those files on disk anywhere. Then if each of them decides to upload a new file, they would each put in a new file, and you would have at most 30K files. The avatar_data column is basically just a pointer to a real file in some storage.


Thanks, Walter.

That was my first instinct, and then I went about following the directions for Assigning the Same File via the Shrine Wiki (can’t link here … because I’m “new”) … and I think the issue is actually that my PromoteJob is getting kicked off … maybe I just need to disable this.

    class PromoteJob < ApplicationJob
      queue_as :default

      def perform(attacher_class, record_class, record_id, name, file_data)
        attacher_class = Object.const_get(attacher_class)
        record         = Object.const_get(record_class).find(record_id) # if using Active Record

        attacher = attacher_class.retrieve(model: record, name: name, file: file_data)
      rescue Shrine::AttachmentChanged, ActiveRecord::RecordNotFound
        # attachment has changed or record has been deleted, nothing to do