1

I'm in the process of migrating from using Paperclip to now using ActiveStorage. I've ran through the migration guide provided here.

I have a Logo model and a School model.

A School has_one_attached :logo and a Logo belongs_to :school

In the console,

school = School.find(119)
school.logo.id

# returns this error :: 
Module::DelegationError Exception: id delegated to attachment, but attachment is nil

The underlying query that gets ran looks like this (this is the problem),

SELECT  "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_id" = $1 AND "active_storage_attachments"."record_type" = $2 AND "active_storage_attachments"."name" = $3 LIMIT $4  [["record_id", 119], ["record_type", "School"], ["name", "logo"], ["LIMIT", 1]]

I don't understand why the query is searching the ACTIVE_STORAGE_ATTACHMENTS table for a record that has a School record_type and the record_id of my School object. It should be searching that table for a Logo type and the id of my Logo object.

In my DB, I do have a Logo record and the id of that record is mapped to the record_id column of the ACTIVE_STORAGE_ATTACHMENTS table and that record has a blob_id which maps to the id column on the ACTIVE_STORAGE_BLOBS table and that contains the info for the correct image.

So it seems like everything data wise is correct.

Does anyone know why the underlying SQL query that is being executed is looking for the wrong type and id, resulting in the id delegated to attachment, but attachment is nil error?

Chiefwarpaint
  • 643
  • 2
  • 12
  • 25
  • It seems like the underlying SQL query is looking for the *correct* `type` and `id`. Your `School has_one_attached :logo`. The `logo` should be an `ActiveStorage::Attachment` which `belongs_to :record, polymorphic: true, touch: true`. So, when you try to find the `logo`, you're going to execute a polymorphic find using `school` which is exactly what's happening. Is the `Logo` class a legacy/artifact of `Paperclip`? It seems like that model is not needed with `ActiveStorage`. – jvillian Nov 05 '19 at 14:32
  • @jvillian The `Logo` model is the original model that was "backed" by `Paperclip` and now I'd like it to instead be "backed" by `ActiveStorage`. Which seems to now know that it should be "backed" by `ActiveStorage`, except that the query is searching for `school` type instead of `logo` type. – Chiefwarpaint Nov 05 '19 at 14:41
  • Because `School has_one_attached :logo`. It's searching for `School` because that's exactly what you told it to do when you said `School has_one_attached :logo`. With `ActiveStorage`, you don't use a `Logo` class. You use `ActiveStorage::Attachment` which, in the case of `School` has a `name` equal to `logo`. – jvillian Nov 05 '19 at 15:03
  • @jvillian So are you proposing that I should delete the `Logo` model? – Chiefwarpaint Nov 05 '19 at 15:08
  • Welp, what to do with your `Logo` class is entirely dependent upon where you are in your migration process. I'm not making any proposals with regards to your `Logo` class. What you need to understand, and I'm not sure you're getting, is that your expectation that the 'underlying SQL query' should be 'looking for' a record with a 'Logo' type is entirely wrong. The query is looking for the exact correct record type, which is `School`. – jvillian Nov 05 '19 at 15:15
  • @jvillian Thank you for your patience as I try to process and understand this. I think maybe my misunderstanding is coming from [here](https://edgeguides.rubyonrails.org/active_storage_overview.html#has-one-attached). For that particular example, I guess I would expect that the `ACTIVE_STORAGE_ATTACHMENTS` table would have rows where the `record_type` is `Avatar`. Would that not be correct? – Chiefwarpaint Nov 05 '19 at 15:30
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/201890/discussion-between-jvillian-and-chiefwarpaint). – jvillian Nov 05 '19 at 15:46

1 Answers1

0

Based on a lengthy chat, the answer is that your legacy model structure (School + Logo) is not parallel to the model structure assumed in the migration guide (User only). Therefore, you cannot simply copy-and-paste the script as provided and expect it to run successfully.

To successfully migrate to ActiveStorage, you will need to modify the script provided in the migration guide to suite your particular model structure.

jvillian
  • 19,953
  • 5
  • 31
  • 44