-
Notifications
You must be signed in to change notification settings - Fork 21.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow configure services for individual attachments #34935
Allow configure services for individual attachments #34935
Conversation
c9ea062
to
b3d16cc
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In order to migrate existing apps users would have to re-run rails active_storage:install and rails db:migrate to add a new migration, suggestions are welcome :)
Can we make the presence of service_name
column optional?
Right now we check for it in the macroses (https://github.com/rails/rails/pull/34935/files#diff-fc054319f93d887d4427a7a728670ba9R159), but we still rely on service_name
column in Blob#service
.
What about extracting this feature check (say, ActiveStorage.per_blob_service_supported?
) and re-use in Blob#service
to avoid calling #service_name
?
configs = Rails.configuration.active_storage.service_configurations | ||
|
||
begin | ||
ActiveStorage::Service.configure service_name, configs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would build a new service instance for each blob–we need some kind of memoization here (ServiceRegistry.fetch
?). That could also allow us to move exception handling logic there and make #service
method much more readable:
def service
ActiveStorage::ServiceRegistry.fetch(service_name, self.class.service)
end
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added memoization, but it looks hard to move exception handling to the same place cause error messages are different enough
398c000
to
f5d5fa6
Compare
activestorage/db/migrate/20190112182829_add_service_name_to_active_storage_blobs.rb
Outdated
Show resolved
Hide resolved
`RuntimeError`. | ||
|
||
NOTE: if you've initialized ActiveStorage before this feature was shipped, Rails would | ||
ask you to generate and execute one more migration (`rails active_storage:install && rails db:migrate`). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can remove this NOTE
when following the approach described in #34935 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✔️
717ee50
to
b19d802
Compare
activestorage/db/update_migrate/20190112182829_add_service_name_to_active_storage_blobs.rb
Outdated
Show resolved
Hide resolved
43b8441
to
e40eb8f
Compare
Hey all, just came across this PR while browsing other I just recently opened #35290 that adds the ability to configure attachments. I don't want to get ahead of myself and assume that change will be accepted. But if it is accepted I wanted to suggest that we could use that same mechanism here when configuring the service. class User < ApplicationRecord
has_one_attached :avatar do |attachment|
attachment.service :s3
end
end Just a thought. Thanks! |
Hi @abhchand, thanks for letting me know! I would add it to my PR if yours will be accepted earlier |
There is no activity on this PR, but will be nice to have this feature in Rails 6.0 |
Hi @iggant, thanks for the support, I'd like to have it merged too :) The only conflict is in the changelog so it shouldn't be a blocker for a review. I believe core team members are busy polishing release candidates |
@bogdanvlviv Can you please review this PR again, will be very nice to have this feature in new major Rails release |
Lack of this feature is the one thing preventing me from moving to ActiveStorage. I'd love to see this get implemented soon. Thanks for the hard work! |
Hi @georgeclaghorn, is there a chance this PR can fit into 6.0.0? 🙂 |
I’m afraid it’s not going to make 6.0. Sorry. |
e3471c0
to
e7f798c
Compare
Hi @DmitryTsepelev, From which version of rails, we can use this? |
Hi @Hareramrai, it's still in the main CHANGELOG so I guess it will be released as part of 6.1. |
@DmitryTsepelev does your merged PR allow for different S3 bucket names to be usable per attachment, or just the toggle of storage types? Is a service "s3" or is it granular down to the bucket name? |
@dnalbach The line # storage.yml
s3_avatars:
service: S3
bucket: "photos"
access_key_id: "..."
secret_access_key: "..."
s3_cover_photos:
service: S3
bucket: "cover_photos"
access_key_id: "..."
secret_access_key: "..." class User < ApplicationRecord
has_one_attached :avatar, service: :s3_avatars
has_one_attached :cover_photo, service: :s3_cover_photos
end |
Thats awsome @DmitryTsepelev , exactly what I was hoping for. This is a BigDeal in the cloud world I live in. Desperately needed. Look forward to seeing your contribution released! |
Hi! This is a great feature and I really appreciate the work done on it! I've opted to start using master on my app to take advantage of this new feature. One thing I did notice is that the ergonomics of the system becomes a bit awkward with testing environments. Originally I had: class Model < ApplicationModel
has_one_attached :thing, service: :s3
end But my tests started trying to upload to S3 😅 It was a simple fix for now: class Model < ApplicationModel
has_one_attached :thing, service: (Rails.env.test? ? :local : :s3)
end But I was wondering if you had thought of some better ergonomics for this given that a ternary statement for every override could become quite awkward. Other things I've considered are:
Again, great feature - would love to hear if anyone had any thoughts on a better solution here 🙇 |
Hi @jules2689, I'm going to recommend you a trick that will work for your specific case only (s3/disk pair), but it will probably will save a lot of time. Have you heard about minio? It's an S3–compatible storage, you can run it locally and keep using "S3" both in prod and dev |
A better option would be to support per-environment configuration in # storage.yml
production:
images:
service: s3
documents:
service: gcloud
test:
images:
service: disk
documents:
service: disk And then you just have:
IMO, that's the Rails Way of dealing with this problem. |
I am upgrading an existing app to 6.1.0.alpha Why doesn't because of that I don't have service_name in my storage_blob and facing errors. |
|
Should this be in the upgrade guide? See https://discuss.rubyonrails.org/t/problem-with-activestorage-blob-on-upgrade-from-6-0-3-4-to-6-1 |
I've done this using custom configuration in the environment config file (https://guides.rubyonrails.org/configuring.html#custom-configuration) |
…igration In rails/rails#33419, we added this migration to properly upgrade Active Storage from 5.2 to 6.0 On Rails 6.1 `rails app:update` shouldn't add this migration to users' app. Note that, I've left implementation that makes `rails app:update` to generate migrations for users' app that are in `activestorage/db/update_migrate/` because we are likely to need it e.g.: rails/rails#34935, rails/rails#36835.
Idea is taken from this comment
This change allows to configure custom services for individual attachments in the following way:
If specified service is not properly configured -
has_one_attached
would throw an error. Sinceservice_name
is stored insideactive_storage_blobs
table it's also possible that misconfiguration will appear in the realtime - for such cases, there is a special configuration optionRails.application.configuration.active_storage.service_misconfiguration_behavior
, which can take the following values::log
(default),:fallback_to_default
and:raise
.In order to migrate existing apps users would have to re-run
rails active_storage:install
andrails db:migrate
to add a new migration, suggestions are welcome :)On the side note, I've moved
require "database/setup"
to the beginning of the test helper to make it look more like a real boot process - migrations are executed before app starts.