Store attachment scoped to association

Hello.

Background
In my application I have a Company-model with lots of connected models. When these connected models have attached files we want to store them with a prefix scoped to the company they belong to.

We are currently running Shrine 2.19 but are getting ready to update and especially if it can solve this problems for us. We have tried setting up our default_storage and dynamic_storage but cannot quite figure it out.

We would like to have separate stores and tried using:
Shrine.plugin :default_storage,
cache: -> { record.storage_key(:cache) },
store: -> { record.storage_key(:store) }
Shrine.plugin :dynamic_storage
and using regex matches for Shrine.storage.

Problem

This works well but makes the models very hard to work with, since when initializing a connected model with a file we must always assign the company first - otherwise we cannot get the proper storage_keys.

In what way would it be best for us to structure our stores?

Please get back to me if I can clarify anything more, this problem has been hard to wrap my head around… Thank you :slightly_smiling_face:

This works well but makes the models very hard to work with, since when initializing a connected model with a file we must always assign the company first - otherwise we cannot get the proper storage_keys.

I don’t see a way around this. The storage information needs to come from somewhere at the time when Shrine needs to perform an upload or retrieve a URL.

If you have some specific ideas on what you would like Shrine to be able to do, I’m definitely open to that.

No, that is probably true. I am working towards having a separate cache store which is not allowed to rely on any attributes from the record. Then I started thinking about adding three stores: A general cache, a scoped cache and the scoped store. I found some discussions about the multi_cache-plugin but I am not quite sure how I would use it together with default_storage.

What I would want is three default stores:
plugin :default_storage, cache: cache, store: -> { record.storage_key(:store) }, cache_scoped: -> { record.storage_key(:cache) }

Do you have any pointers for doing something like this together with multi_cache?


Regarding what Shrine could do to make my problems easier I am thinking about exception handling. Right now I get exceptions if the block given to default_storage returns nil. Would it be possible to catch these nil-values during validation instead of during execution?

Thank you for a great plugin and for answering!

You can combine the multi_cache plugin with dynamic_storage, in a similar way you’ve described. Note that you can always upload the file ad-hoc and provide the storage, these things don’t need to be configured automatically. See the “Using Attacher” guide for these options.

Regarding raising exception for missing storage during validation, that’s not possible, because Shrine only runs validation after the file has been cached. You can always rescue the error in the controller and add the validation message from there.