shrine 3.1.0 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +82 -0
  3. data/README.md +11 -4
  4. data/doc/advantages.md +4 -4
  5. data/doc/attacher.md +2 -2
  6. data/doc/carrierwave.md +24 -12
  7. data/doc/changing_derivatives.md +1 -1
  8. data/doc/changing_location.md +6 -5
  9. data/doc/design.md +134 -85
  10. data/doc/direct_s3.md +26 -0
  11. data/doc/external/articles.md +57 -45
  12. data/doc/external/extensions.md +41 -35
  13. data/doc/external/misc.md +23 -8
  14. data/doc/getting_started.md +156 -85
  15. data/doc/metadata.md +80 -44
  16. data/doc/multiple_files.md +1 -1
  17. data/doc/paperclip.md +28 -9
  18. data/doc/plugins/add_metadata.md +112 -35
  19. data/doc/plugins/atomic_helpers.md +41 -3
  20. data/doc/plugins/backgrounding.md +12 -2
  21. data/doc/plugins/column.md +36 -7
  22. data/doc/plugins/default_url.md +6 -3
  23. data/doc/plugins/derivatives.md +83 -44
  24. data/doc/plugins/download_endpoint.md +5 -5
  25. data/doc/plugins/dynamic_storage.md +1 -1
  26. data/doc/plugins/entity.md +12 -4
  27. data/doc/plugins/form_assign.md +5 -5
  28. data/doc/plugins/included.md +25 -5
  29. data/doc/plugins/infer_extension.md +9 -0
  30. data/doc/plugins/instrumentation.md +1 -1
  31. data/doc/plugins/metadata_attributes.md +1 -0
  32. data/doc/plugins/mirroring.md +1 -1
  33. data/doc/plugins/model.md +8 -3
  34. data/doc/plugins/persistence.md +10 -1
  35. data/doc/plugins/remote_url.md +6 -1
  36. data/doc/plugins/remove_invalid.md +9 -1
  37. data/doc/plugins/sequel.md +1 -1
  38. data/doc/plugins/store_dimensions.md +10 -0
  39. data/doc/plugins/type_predicates.md +96 -0
  40. data/doc/plugins/upload_endpoint.md +1 -1
  41. data/doc/plugins/upload_options.md +1 -1
  42. data/doc/plugins/url_options.md +4 -4
  43. data/doc/plugins/validation.md +14 -4
  44. data/doc/plugins/versions.md +7 -7
  45. data/doc/processing.md +287 -123
  46. data/doc/refile.md +9 -9
  47. data/doc/release_notes/2.8.0.md +1 -1
  48. data/doc/release_notes/3.0.0.md +1 -1
  49. data/doc/release_notes/3.2.0.md +96 -0
  50. data/doc/release_notes/3.2.1.md +31 -0
  51. data/doc/release_notes/3.2.2.md +14 -0
  52. data/doc/release_notes/3.3.0.md +105 -0
  53. data/doc/release_notes/3.4.0.md +35 -0
  54. data/doc/securing_uploads.md +2 -2
  55. data/doc/storage/memory.md +19 -0
  56. data/doc/storage/s3.md +104 -77
  57. data/doc/testing.md +12 -2
  58. data/doc/upgrading_to_3.md +99 -53
  59. data/lib/shrine.rb +9 -8
  60. data/lib/shrine/attacher.rb +20 -10
  61. data/lib/shrine/attachment.rb +2 -2
  62. data/lib/shrine/plugins.rb +22 -0
  63. data/lib/shrine/plugins/activerecord.rb +3 -3
  64. data/lib/shrine/plugins/add_metadata.rb +20 -5
  65. data/lib/shrine/plugins/backgrounding.rb +2 -2
  66. data/lib/shrine/plugins/default_url.rb +1 -1
  67. data/lib/shrine/plugins/derivation_endpoint.rb +13 -8
  68. data/lib/shrine/plugins/derivatives.rb +59 -30
  69. data/lib/shrine/plugins/determine_mime_type.rb +5 -3
  70. data/lib/shrine/plugins/entity.rb +12 -11
  71. data/lib/shrine/plugins/instrumentation.rb +12 -18
  72. data/lib/shrine/plugins/mirroring.rb +8 -8
  73. data/lib/shrine/plugins/model.rb +3 -3
  74. data/lib/shrine/plugins/presign_endpoint.rb +16 -4
  75. data/lib/shrine/plugins/pretty_location.rb +1 -1
  76. data/lib/shrine/plugins/processing.rb +1 -1
  77. data/lib/shrine/plugins/refresh_metadata.rb +2 -2
  78. data/lib/shrine/plugins/remote_url.rb +3 -3
  79. data/lib/shrine/plugins/remove_attachment.rb +5 -0
  80. data/lib/shrine/plugins/remove_invalid.rb +10 -5
  81. data/lib/shrine/plugins/sequel.rb +1 -1
  82. data/lib/shrine/plugins/store_dimensions.rb +4 -2
  83. data/lib/shrine/plugins/type_predicates.rb +113 -0
  84. data/lib/shrine/plugins/upload_endpoint.rb +10 -5
  85. data/lib/shrine/plugins/upload_options.rb +2 -2
  86. data/lib/shrine/plugins/url_options.rb +2 -2
  87. data/lib/shrine/plugins/validation.rb +9 -7
  88. data/lib/shrine/storage/linter.rb +4 -4
  89. data/lib/shrine/storage/memory.rb +5 -3
  90. data/lib/shrine/storage/s3.rb +117 -38
  91. data/lib/shrine/version.rb +1 -1
  92. data/shrine.gemspec +8 -8
  93. metadata +42 -34
data/doc/direct_s3.md CHANGED
@@ -76,6 +76,7 @@ If you're using [Uppy], this is the recommended CORS configuration for the
76
76
  <AllowedHeader>x-amz-content-sha256</AllowedHeader>
77
77
  <AllowedHeader>content-type</AllowedHeader>
78
78
  <AllowedHeader>content-disposition</AllowedHeader>
79
+ <ExposeHeader>ETag</ExposeHeader>
79
80
  </CORSRule>
80
81
  <CORSRule>
81
82
  <AllowedOrigin>*</AllowedOrigin>
@@ -85,6 +86,31 @@ If you're using [Uppy], this is the recommended CORS configuration for the
85
86
  </CORSConfiguration>
86
87
  ```
87
88
 
89
+ Or in JSON format:
90
+
91
+ ```json
92
+ [
93
+ {
94
+ "AllowedOrigins": [ "https://my-app.com" ],
95
+ "AllowedMethods": [ "GET", "POST", "PUT" ],
96
+ "MaxAgeSeconds": 3000,
97
+ "AllowedHeaders": [
98
+ "Authorization",
99
+ "x-amz-date",
100
+ "x-amz-content-sha256",
101
+ "Content-Type",
102
+ "Content-Disposition"
103
+ ],
104
+ "ExposeHeaders": [ "ETag" ]
105
+ },
106
+ {
107
+ "AllowedOrigins": [ "*" ],
108
+ "AllowedMethods": [ "GET" ],
109
+ "MaxAgeSeconds": 3000
110
+ }
111
+ ]
112
+ ```
113
+
88
114
  Replace `https://my-app.com` with the URL to your app (in development you can
89
115
  set this to `*`). Once you've hit "Save", it may take some time for the
90
116
  new CORS settings to be applied.
@@ -4,48 +4,60 @@ title: Articles
4
4
 
5
5
  ## Official articles
6
6
 
7
- * [Introducing Shrine](http://twin.github.io/introducing-shrine)
8
- * [Asynchronous File Uploads](http://twin.github.io/file-uploads-asynchronous-world)
9
- * [Shrine 2.0 Released](https://twin.github.io/shrine-2-0-released/)
10
- * [Shrine meets Transloadit](https://twin.github.io/shrine-meets-transloadit/)
11
- * [Resumable File Uploads in Ruby](https://twin.github.io/resumable-file-uploads-in-ruby/)
12
- * [Adding Direct S3 Uploads to a Roda App with Shrine](https://github.com/shrinerb/shrine/wiki/Adding-Direct-S3-Uploads)
13
- * [Adding Resumable Uploads to a Roda App with Shrine](https://github.com/shrinerb/shrine/wiki/Adding-Resumable-Uploads)
14
- * [Better File Uploads with Shrine: Motivation](https://twin.github.io/better-file-uploads-with-shrine-motivation/)
15
- * [Better File Uploads with Shrine: Uploader](https://twin.github.io/better-file-uploads-with-shrine-uploader/)
16
- * [Better File Uploads with Shrine: Attachment](https://twin.github.io/better-file-uploads-with-shrine-attachment/)
17
- * [Better File Uploads with Shrine: Processing](https://twin.github.io/better-file-uploads-with-shrine-processing/)
18
- * [Better File Uploads with Shrine: Metadata](https://twin.github.io/better-file-uploads-with-shrine-metadata/)
19
- * [Better File Uploads with Shrine: Direct Uploads](https://twin.github.io/better-file-uploads-with-shrine-direct-uploads)
20
- * [Shrine 3.0 Released](https://twin.github.io/shrine-3-0-released/)
21
-
22
- ## Other Articles
23
-
24
- * [Uploading files with Shrine in Hanami](http://katafrakt.me/2016/02/04/shrine-hanami-uploads/)
25
- * [Rails File Uploading You Can Believe in with Shrine](http://www.sitepoint.com/rails-file-uploading-you-can-believe-in-with-shrine/)
26
- * [Uploading Files With Rails and Shrine](https://code.tutsplus.com/tutorials/uploading-files-with-rails-and-shrine--cms-27596)
27
- * [Upload images using Shrine.rb and Dropzone.js](https://codyeatworld.com/2017/04/18/rails-uploading-images-confidently-with-shrine-rb/)
28
- * [Background file uploads to S3 using Shrine](http://elixirator.com/blog/2017/background-file-uploads-to-s3-using-shrine.html)
29
- * [Rails + Shrine + DropzoneJS](https://stephencodes.com/rails-5-shrine-dropzonejs/)
30
- * [Uploading Files with Rails and ActionCable](https://scotch.io/tutorials/uploading-files-with-rails-and-actioncable)
31
- * [Creating Streaming Radio With Rails and Icecast](https://scotch.io/tutorials/creating-online-streaming-radio-with-rails-and-icecast)
32
- * [Multiple Photo Upload using Shrine](https://github.com/pyksoft/multi-photo-upload#multiple-photo-upload-using-shrine)
33
- * [Store Your Files on S3: Setup & Configuration](https://www.ironin.it/blog/store-your-files-on-s3-using-the-ruby-shrine-gem-part-1.html)
34
- * [Store Your Files on S3: Direct Uploads](https://www.ironin.it/blog/store-your-files-on-s3-using-the-ruby-shrine-gem-part-2.html)
35
- * [Store Your Files on S3: Uploading from a URL](https://www.ironin.it/blog/store-your-files-on-s3-using-the-ruby-shrine-gem-part-3.html)
36
- * [How to use Trix and Shrine for WYSIWYG Editing with Drag-and-Drop Image Uploading](http://headway.io/blog/how-to-use-trix-and-shrine-for-wysiwyg-editing-with-drag-and-drop-image-uploading/)
37
- * [Happy users uploading files with Rails 5, Shrine, and Vue.js](https://itnext.io/happy-users-uploading-files-with-rails-5-shrine-and-vue-js-bbcc470a327f)
38
- * [Notes on study of shrine implementation](https://bibwild.wordpress.com/2018/09/12/notes-on-study-of-shrine-implementation/)
39
- * [GraphQL file upload with Shrine](https://blog.stanko.io/graphql-file-upload-with-shrine-45fa26463c68)
40
-
41
- ## Videos
42
-
43
- * [wroc_love.rb Handling file uploads for a modern developer](https://www.youtube.com/watch?v=fP2JGjTZU2s)
44
- * [File Uploads in Rails with Shrine (GoRails)](https://gorails.com/episodes/file-uploading-with-shrine?autoplay=1)
45
- * [Direct File Uploads to S3: Part 1 (GoRails)](https://gorails.com/episodes/direct-file-uploads-to-s3-part-1?autoplay=1)
46
- * [Direct File Uploads to S3: Part 2 (GoRails)](https://gorails.com/episodes/direct-file-uploads-to-s3-part-2?autoplay=1)
47
- * [Direct File Uploads to S3: Part 3 (GoRails)](https://gorails.com/episodes/direct-file-uploads-to-s3-part-3?autoplay=1)
48
- * [Backgrounding and Video Transcoding (GoRails)](https://gorails.com/episodes/shrine-background-and-video-transcoding?autoplay=1)
49
- * [Multiple File Uploads with Shrine (GoRails)](https://gorails.com/episodes/multiple-file-uploads-with-shrine?autoplay=1)
50
- * [Trix WYSIWYG Editor And File Uploads (GoRails)](https://gorails.com/episodes/trix-editor?autoplay=1)
51
- * [Uploading Files to DigitalOcean Spaces (GoRails)](https://gorails.com/episodes/digital-ocean-spaces-with-rails?autoplay=1)
7
+ | Article | Published |
8
+ | :------- | --------: |
9
+ | [Better File Uploads with Shrine: Eager Processing](https://twin.github.io/better-file-uploads-with-shrine-eager-processing) | 12&nbsp;Dec&nbsp;2019 |
10
+ | [Shrine 3.0 Released](https://twin.github.io/shrine-3-0-released/) | 14&nbsp;Oct&nbsp;2019 |
11
+ | [Upcoming Features in Shrine 3.0](https://twin.github.io/upcoming-features-in-shrine-3-0/) | 29&nbsp;Aug&nbsp;2019 |
12
+ | [Better File Uploads with Shrine: Direct Uploads](https://twin.github.io/better-file-uploads-with-shrine-direct-uploads/) | 08&nbsp;Jan&nbsp;2018 |
13
+ | [Better File Uploads with Shrine: Metadata](https://twin.github.io/better-file-uploads-with-shrine-metadata/) | 07&nbsp;Nov&nbsp;2016 |
14
+ | [Better File Uploads with Shrine: Processing](https://twin.github.io/better-file-uploads-with-shrine-processing/) | 31&nbsp;Oct&nbsp;2016 |
15
+ | [Better File Uploads with Shrine: Attachment](https://twin.github.io/better-file-uploads-with-shrine-attachment/) | 17&nbsp;Sep&nbsp;2016 |
16
+ | [Better File Uploads with Shrine: Uploader](https://twin.github.io/better-file-uploads-with-shrine-uploader/) | 16&nbsp;Sep&nbsp;2016 |
17
+ | [Better File Uploads with Shrine: Motivation](https://twin.github.io/better-file-uploads-with-shrine-motivation/) | 11&nbsp;Sep&nbsp;2016 |
18
+ | [Resumable File Uploads in Ruby](https://twin.github.io/resumable-file-uploads-in-ruby/) | 04&nbsp;Sep&nbsp;2016 |
19
+ | [Shrine meets Transloadit](https://twin.github.io/shrine-meets-transloadit/) | 11&nbsp;Jul&nbsp;2016 |
20
+ | [Shrine 2.0 Released](https://twin.github.io/shrine-2-0-released/) | 20&nbsp;May&nbsp;2016 |
21
+ | [Asynchronous File Uploads](http://twin.github.io/file-uploads-asynchronous-world) | 18&nbsp;Jan&nbsp;2016 |
22
+ | [Introducing Shrine](http://twin.github.io/introducing-shrine) | 04&nbsp;Oct&nbsp;2015 |
23
+
24
+ ## Community articles
25
+
26
+ | Article | Published |
27
+ | :------ | --------: |
28
+ | [Microsoft Azure data storage library](https://syndicode.com/2019/12/17/microsoft-azure-data-storage-library-rewrite-the-existing-library-to-get-things-done/) | 17&nbsp;Dec&nbsp;2019 |
29
+ | [How to use REST clients / native apps to make Shrine client uploads and S3 work for you (no Javascript, just backend)](https://dev.to/rob117/how-to-use-rest-clients--native-apps-to-make-shrine-client-uploads-and-s3-work-for-you-no-javascript-just-backend-322h) | 16&nbsp;Feb&nbsp;2019 |
30
+ | [GraphQL file upload with Shrine](https://blog.stanko.io/graphql-file-upload-with-shrine-45fa26463c68) | 02&nbsp;Jan&nbsp;2019 |
31
+ | [Notes on study of shrine implementation](https://bibwild.wordpress.com/2018/09/12/notes-on-study-of-shrine-implementation/) | 12&nbsp;Sep&nbsp;2018 |
32
+ | [Happy users uploading files with Rails 5, Shrine, and Vue.js](https://itnext.io/happy-users-uploading-files-with-rails-5-shrine-and-vue-js-bbcc470a327f) | 04&nbsp;Sep&nbsp;2018 |
33
+ | [Rails 5 + Shrine + DropzoneJS](https://stephencodes.com/rails-5-shrine-dropzonejs/) | 20&nbsp;Oct&nbsp;2018 |
34
+ | [How to use Trix and Shrine for WYSIWYG Editing with Drag-and-Drop Image Uploading](http://headway.io/blog/how-to-use-trix-and-shrine-for-wysiwyg-editing-with-drag-and-drop-image-uploading/) | 26&nbsp;Jan&nbsp;2018 |
35
+ | [Store Your Files on S3: Part 3 – Uploading from a URL](https://www.ironin.it/blog/store-your-files-on-s3-using-the-ruby-shrine-gem-part-3.html) | 28&nbsp;Dec&nbsp;2017 |
36
+ | [Store Your Files on S3: Part 2 Direct Uploads](https://www.ironin.it/blog/store-your-files-on-s3-using-the-ruby-shrine-gem-part-2.html) | 15&nbsp;Dec&nbsp;2017 |
37
+ | [Store Your Files on S3: Part 1 Setup & Configuration](https://www.ironin.it/blog/store-your-files-on-s3-using-the-ruby-shrine-gem-part-1.html) | 27&nbsp;Nov&nbsp;2017 |
38
+ | [Creating Streaming Radio With Rails and Icecast](https://scotch.io/tutorials/creating-online-streaming-radio-with-rails-and-icecast) | 06&nbsp;Nov&nbsp;2017 |
39
+ | [Multiple Photo Upload using Shrine](https://github.com/pyksoft/multi-photo-upload#multiple-photo-upload-using-shrine) | 02&nbsp;Nov&nbsp;2017 |
40
+ | [Uploading Files with Rails and ActionCable](https://scotch.io/tutorials/uploading-files-with-rails-and-actioncable) | 19&nbsp;Oct&nbsp;2017 |
41
+ | [Background file uploads to S3 using Shrine](https://elixirator.com/blog/background-file-uploads-to-s3-using-shrine/) | 21&nbsp;Jul&nbsp;2017 |
42
+ | [Upload images using Shrine.rb and Dropzone.js](https://codyeatworld.com/2017/04/18/rails-uploading-images-confidently-with-shrine-rb/) | 18&nbsp;Apr&nbsp;2017 |
43
+ | [Uploading Files With Rails and Shrine](https://code.tutsplus.com/tutorials/uploading-files-with-rails-and-shrine--cms-27596) | 26&nbsp;Dec&nbsp;2016 |
44
+ | [Rails File Uploading You Can Believe in with Shrine](http://www.sitepoint.com/rails-file-uploading-you-can-believe-in-with-shrine/) | 11&nbsp;Apr&nbsp;2016 |
45
+ | [Uploading files with Shrine in Hanami](http://katafrakt.me/2016/02/04/shrine-hanami-uploads/) | 04&nbsp;Feb&nbsp;2016 |
46
+
47
+ ## Screencasts
48
+
49
+ | Screencast | Source | Published |
50
+ | :---- | :------ | --------: |
51
+ | [Testing File Uploads in Rails with Shrine](https://gorails.com/episodes/testing-file-uploads-with-shrine?autoplay=1) | GoRails | 23&nbsp;Mar&nbsp;2020 |
52
+ | [File Uploads in Rails with Shrine](https://gorails.com/episodes/rails-file-uploads-with-shrine?autoplay=1) | GoRails | 16&nbsp;Mar&nbsp;2020 |
53
+ | [Uploading Files to DigitalOcean Spaces](https://gorails.com/episodes/digital-ocean-spaces-with-rails?autoplay=1) | GoRails | 31&nbsp;Oct&nbsp;2017 |
54
+ | [Trix WYSIWYG Editor And File Uploads](https://gorails.com/episodes/trix-editor?autoplay=1) | GoRails | 03&nbsp;Oct&nbsp;2017 |
55
+ | [Multiple File Uploads with Shrine](https://gorails.com/episodes/multiple-file-uploads-with-shrine?autoplay=1) | GoRails | 14&nbsp;Dec&nbsp;2016 |
56
+ | [Backgrounding and Video Transcoding](https://gorails.com/episodes/shrine-background-and-video-transcoding?autoplay=1) | GoRails | 03&nbsp;Nov&nbsp;2016 |
57
+
58
+ ## Talks
59
+
60
+ | Talk | Source | Date |
61
+ | :---- | :------ | --------: |
62
+ | [Handling file uploads for a modern developer](https://www.youtube.com/watch?v=fP2JGjTZU2s) | wroc_love.rb | 24&nbsp;Mar&nbsp;2019 |
63
+ | [Shrine – Handle File Uploads like it's 2017](https://www.youtube.com/watch?v=plD-RkKEay0) | Melbourne Ruby | 27&nbsp;Feb&nbsp;2017 |
@@ -4,44 +4,50 @@ title: Extensions
4
4
 
5
5
  ## Storages
6
6
 
7
- * [shrine-aliyun-oss](https://github.com/zillou/shrine-aliyun-oss)
8
- * [shrine-cloudinary](https://github.com/shrinerb/shrine-cloudinary)
9
- * [shrine-flickr](https://github.com/shrinerb/shrine-flickr)
10
- * [shrine-fog](https://github.com/shrinerb/shrine-fog)
11
- * [shrine-ftp](https://github.com/ProjectResound/shrine-ftp)
12
- * [shrine-google_cloud_storage](https://github.com/renchap/shrine-google_cloud_storage)
13
- * [shrine-gdrive_storage](https://github.com/edwardsharp/shrine-gdrive_storage)
14
- * [shrine-gridfs](https://github.com/shrinerb/shrine-gridfs)
15
- * [shrine-imgix](https://github.com/shrinerb/shrine-imgix)
16
- * [shrine-memory](https://github.com/shrinerb/shrine-memory)
17
- * [shrine-redis](https://github.com/dbongo/shrine-redis)
18
- * [shrine-scp](https://github.com/jordanandree/shrine-scp)
19
- * [shrine-sql](https://github.com/shrinerb/shrine-sql)
20
- * [shrine-thumbor](https://github.com/havran/shrine-thumbor)
21
- * [shrine-transloadit](https://github.com/shrinerb/shrine-transloadit)
22
- * [shrine-uploadcare](https://github.com/shrinerb/shrine-uploadcare)
23
- * [shrine-url](https://github.com/shrinerb/shrine-url)
24
- * [shrine-storage-you_tube](https://github.com/thedyrt/shrine-storage-you_tube)
25
- * [shrine-webdav](https://github.com/funbox/shrine-webdav)
7
+ | Gem | Description |
8
+ | :---- | :---------- |
9
+ | [shrine-aliyun-oss](https://github.com/zillou/shrine-aliyun-oss) | Storage using [Alibaba Cloud OSS](https://www.alibabacloud.com/product/oss) |
10
+ | [shrine-cloudinary](https://github.com/shrinerb/shrine-cloudinary) | Storage using [Cloudinary](https://cloudinary.com/) |
11
+ | [shrine-flickr](https://github.com/shrinerb/shrine-flickr) | Storage using [Flickr](https://flickr.com/) |
12
+ | [shrine-fog](https://github.com/shrinerb/shrine-fog) | Storage using [Fog](http://fog.io/) |
13
+ | [shrine-ftp](https://github.com/ProjectResound/shrine-ftp) | Storage using an FTP server |
14
+ | [shrine-google_cloud_storage](https://github.com/renchap/shrine-google_cloud_storage) | Storage using [Google Cloud Storage](https://cloud.google.com/storage/) |
15
+ | [shrine-gdrive_storage](https://github.com/edwardsharp/shrine-gdrive_storage) | Storage using [Google Drive](https://www.google.com/drive/) |
16
+ | [shrine-gridfs](https://github.com/shrinerb/shrine-gridfs) | Storage using [Mongo GridFS](https://docs.mongodb.com/manual/core/gridfs/) |
17
+ | [shrine-redis](https://github.com/dbongo/shrine-redis) | Storage using [Redis](https://redis.io/) |
18
+ | [shrine-scp](https://github.com/jordanandree/shrine-scp) | Storage using `scp` |
19
+ | [shrine-sql](https://github.com/shrinerb/shrine-sql) | Storage using an SQL database |
20
+ | [shrine-uploadcare](https://github.com/shrinerb/shrine-uploadcare) | Storage using [Uploadcare](https://uploadcare.com) |
21
+ | [shrine-url](https://github.com/shrinerb/shrine-url) | Storage for handling remote URLs |
22
+ | [shrine-storage-you_tube](https://github.com/thedyrt/shrine-storage-you_tube) | Storage using [YouTube](https://www.youtube.com/) |
23
+ | [shrine-webdav](https://github.com/funbox/shrine-webdav) | Storage using a [WebDAV](https://en.wikipedia.org/wiki/WebDAV) server |
26
24
 
27
25
  ## Plugins
28
26
 
29
- * [administrate-field-shrine](https://github.com/catsky/administrate-field-shrine)
30
- * [rails_admin_shrine](https://github.com/iquest/rails_admin_shrine)
31
- * [shrine-color](https://github.com/jnylen/shrine-color)
32
- * [shrine-configurable_storage](https://github.com/SleeplessByte/shrine-configurable_storage)
33
- * [shrine-content_addressable](https://github.com/SleeplessByte/shrine-content_addressable)
34
- * [shrine-lambda](https://github.com/texpert/shrine-lambda)
35
- * [hanami-shrine](https://github.com/katafrakt/hanami-shrine)
36
- * [shrine-mongoid](https://github.com/shrinerb/shrine-mongoid)
37
- * [shrine-rails](https://github.com/abepetrillo/shrine-rails)
38
- * [shrine-reform](https://github.com/shrinerb/shrine-reform)
39
- * [shrine-rom](https://github.com/shrinerb/shrine-rom)
40
- * [shrine-tus](https://github.com/shrinerb/shrine-tus)
27
+ | Gem | Description |
28
+ | :---- | :-------- |
29
+ | [administrate-field-shrine](https://github.com/catsky/administrate-field-shrine) | Plugin for [Administrate](https://github.com/thoughtbot/administrate) |
30
+ | [rails_admin_shrine](https://github.com/iquest/rails_admin_shrine) | Plugin for [RailsAdmin](https://github.com/sferik/rails_admin) |
31
+ | [shrine-blurhash](https://github.com/renchap/shrine-blurhash) | Plugin for computing [Blurhash](https://blurha.sh/) on images |
32
+ | [shrine-cloudimage](https://github.com/janklimo/shrine-cloudimage) | Plugin for [Cloudimage](https://www.cloudimage.io/) |
33
+ | [shrine-color](https://github.com/jnylen/shrine-color) | Plugin for finding dominant color in an image |
34
+ | [shrine-configurable_storage](https://github.com/SleeplessByte/shrine-configurable_storage) | Plugin for lazy storage registration |
35
+ | [shrine-content_addressable](https://github.com/SleeplessByte/shrine-content_addressable) | Plugin for generating content addressable locations |
36
+ | [shrine-imgix](https://github.com/shrinerb/shrine-imgix) | Plugin for [Imgix](https://www.imgix.com/) |
37
+ | [shrine-transloadit](https://github.com/shrinerb/shrine-transloadit) | Plugin for [Transloadit](https://transloadit.com/) |
38
+ | [shrine-lambda](https://github.com/texpert/shrine-lambda) | Plugin for [AWS Lambda](https://aws.amazon.com/lambda/) |
39
+ | [hanami-shrine](https://github.com/katafrakt/hanami-shrine) | Plugin for [Hanami](https://hanamirb.org/) |
40
+ | [shrine-mongoid](https://github.com/shrinerb/shrine-mongoid) | Plugin for [Mongoid](https://mongoid.org) |
41
+ | [shrine-rails](https://github.com/abepetrillo/shrine-rails) | Plugin for [Rails](https://rubyonrails.org/) |
42
+ | [shrine-rom](https://github.com/shrinerb/shrine-rom) | Plugin for [ROM](https://rom-rb.org/) |
43
+ | [shrine-tus](https://github.com/shrinerb/shrine-tus) | Plugin for [tus](https://tus.io) server integration |
41
44
 
42
45
  ## Libraries
43
46
 
44
- * [ckeditor](https://github.com/galetahub/ckeditor)
45
- * [imgproxy](https://github.com/imgproxy/imgproxy.rb)
46
- * [rails_admin](https://github.com/sferik/rails_admin)
47
- * [uppy-s3_multipart](https://github.com/janko/uppy-s3_multipart)
47
+ | Gem | Description |
48
+ | :----- | :------- |
49
+ | [ckeditor](https://github.com/galetahub/ckeditor) | Integration for [CKEditor](https://ckeditor.com/ckeditor-4/) |
50
+ | [faster_s3_url](https://github.com/jrochkind/faster_s3_url) | Optimized generation of public and presigned AWS S3 GET URLs |
51
+ | [imgproxy](https://github.com/imgproxy/imgproxy.rb) | Integration for [imgproxy](https://github.com/imgproxy/imgproxy) |
52
+ | [rails_admin](https://github.com/sferik/rails_admin) | Integration for [RailsAdmin](https://github.com/sferik/rails_admin) |
53
+ | [uppy-s3_multipart](https://github.com/janko/uppy-s3_multipart) | Integration for [Uppy AWS S3 Multipart](https://uppy.io/docs/aws-s3-multipart/) |
data/doc/external/misc.md CHANGED
@@ -4,14 +4,29 @@ title: Miscellaneous
4
4
 
5
5
  ## Demos
6
6
 
7
- * [Dropzone demo](https://github.com/codyeatworld/example-shrine-dropzone)
8
- * [Hanami demo](https://github.com/katafrakt/hanami-shrine-example)
9
- * [Rails demo](https://github.com/erikdahlstrand/shrine-rails-example)
10
- * [Resumable uploads demo](https://github.com/shrinerb/shrine-tus-demo)
11
- * [Roda demo (official)](https://github.com/shrinerb/shrine/tree/master/demo)
12
- * [ROM & dry-rb demo](https://github.com/shrinerb/shrine-rom/tree/master/demo)
13
- * [Transloadit demo](https://github.com/shrinerb/shrine-transloadit/tree/master/demo)
7
+ | Demo | Description |
8
+ | :--- | :---------- |
9
+ | [Dropzone demo](https://github.com/codyeatworld/example-shrine-dropzone) | Shows direct upload using [Dropzone.js] |
10
+ | [Hanami demo](https://github.com/katafrakt/hanami-shrine-example) | Shows file attachment in [Hanami] |
11
+ | [Crop demo](https://github.com/shrinerb/shrine-crop-example) | Shows image cropping using [Cropper.js] |
12
+ | [Rails demo](https://github.com/erikdahlstrand/shrine-rails-example) | Shows direct upload in [Rails] |
13
+ | [Resumable uploads demo](https://github.com/shrinerb/shrine-tus-demo) | Shows resumable direct upload on [tus] |
14
+ | [Roda demo (official)](https://github.com/shrinerb/shrine/tree/master/demo) | Shows direct upload in [Roda] |
15
+ | [rom-rb & dry-rb demo](https://github.com/shrinerb/shrine-rom/tree/master/demo) | Shows file attachment with [rom-rb] and [dry-rb] |
16
+ | [Transloadit demo](https://github.com/shrinerb/shrine-transloadit/tree/master/demo) | Shows file processing using [Transloadit] |
14
17
 
15
18
  ## Projects
16
19
 
17
- * [Cortex CMS](https://docs.cortexcms.org)
20
+ | Project | Description |
21
+ | :------ | :---------- |
22
+ | [CortexCMS](https://docs.cortexcms.org) | An open source, enterprise content management and distribution platform |
23
+
24
+ [Dropzone.js]: https://www.dropzonejs.com/
25
+ [Hanami]: https://hanamirb.org/
26
+ [Cropper.js]: https://github.com/fengyuanchen/cropperjs
27
+ [Rails]: https://rubyonrails.org/
28
+ [tus]: https://tus.io/
29
+ [Roda]: https://roda.jeremyevans.net/
30
+ [rom-rb]: https://rom-rb.org/
31
+ [dry-rb]: https://dry-rb.org/
32
+ [Transloadit]: https://transloadit.com/
@@ -37,22 +37,26 @@ will use to store all information about the attachment:
37
37
  ```rb
38
38
  Sequel.migration do
39
39
  change do
40
- add_column :photos, :image_data, :text # or :jsonb
40
+ add_column :photos, :image_data, :text # or :jsonb
41
41
  end
42
42
  end
43
43
  ```
44
+
44
45
  <!--ActiveRecord-->
45
46
  ```rb
46
47
  class AddImageDataToPhotos < ActiveRecord::Migration
47
48
  def change
48
- add_column :photos, :image_data, :text # or :jsonb
49
+ add_column :photos, :image_data, :text # or :jsonb
49
50
  end
50
51
  end
51
52
  ```
53
+
52
54
  <!--Rails-->
55
+ ```rb
56
+ $ rails generate migration add_image_data_to_photos image_data:text # or image_data:jsonb
53
57
  ```
54
- $ rails generate migration add_image_data_to_photos image_data:text
55
- ```
58
+ If using `jsonb` consider adding a [gin index] for fast key-value pair searchability within `image_data`.
59
+
56
60
  <!--END_DOCUSAURUS_CODE_TABS-->
57
61
 
58
62
  Now you can create an uploader class for the type of files you want to upload,
@@ -110,6 +114,14 @@ form @photo, action: "/photos", enctype: "multipart/form-data" do |f|
110
114
  f.button "Create"
111
115
  end
112
116
  ```
117
+ <!--HTML-->
118
+ ```erb
119
+ <form action="/photos" method="post" enctype="multipart/form-data">
120
+ <input name="photo[image]" type="hidden" value="<%= @photo.cached_image_data %>" />
121
+ <input name="photo[image] "type="file" />
122
+ <input type="submit" value="Create" />
123
+ </form>
124
+ ```
113
125
  <!--END_DOCUSAURUS_CODE_TABS-->
114
126
 
115
127
  Note that the file field needs to go *after* the hidden field, so that
@@ -167,9 +179,13 @@ specific storage service, by implementing a common public interface. Storage
167
179
  instances are registered under an identifier in `Shrine.storages`, so that they
168
180
  can later be used by [uploaders][uploader].
169
181
 
170
- Previously we've shown the [FileSystem] storage which saves files to disk, but
171
- Shrine also ships with [S3] storage which stores files on [AWS S3] (or any
172
- S3-compatible service such as [DigitalOcean Spaces] or [MinIO]).
182
+ Shrine ships with the following storages:
183
+
184
+ * [`Shrine::Storage::FileSystem`][FileSystem] stores files on disk
185
+ * [`Shrine::Storage::S3`][S3] – stores files on [AWS S3] (or [DigitalOcean Spaces], [MinIO], ...)
186
+ * [`Shrine::Storage::Memory`][Memory] – stores file in memory (convenient for [testing][Testing with Shrine])
187
+
188
+ Here is how we might configure Shrine with S3 storage:
173
189
 
174
190
  ```rb
175
191
  # Gemfile
@@ -180,9 +196,9 @@ require "shrine/storage/s3"
180
196
 
181
197
  s3_options = {
182
198
  bucket: "<YOUR BUCKET>", # required
199
+ region: "<YOUR REGION>", # required
183
200
  access_key_id: "<YOUR ACCESS KEY ID>",
184
201
  secret_access_key: "<YOUR SECRET ACCESS KEY>",
185
- region: "<YOUR REGION>",
186
202
  }
187
203
 
188
204
  Shrine.storages = {
@@ -196,9 +212,9 @@ suitable for [direct uploads][presigned upload]. The `:cache` and `:store`
196
212
  names are special only in terms that the [attacher] will automatically pick
197
213
  them up, you can also register more storage objects under different names.
198
214
 
199
- See the [FileSystem] and [S3] storage docs for more details. There are [many
200
- more Shrine storages][storages] provided by external gems, and you can also
201
- [create your own storage][Creating Storages].
215
+ See the [FileSystem]/[S3]/[Memory] storage docs for more details. There are
216
+ [many more Shrine storages][storages] provided by external gems, and you can
217
+ also [create your own storage][Creating Storages].
202
218
 
203
219
  ## Uploader
204
220
 
@@ -256,14 +272,14 @@ Shrine is able to upload any IO-like object that implement methods [`#read`],
256
272
  [`#rewind`], [`#eof?`] and [`#close`] whose behaviour matches the [`IO`] class.
257
273
  This includes but is not limited to the following objects:
258
274
 
259
- * `File`
260
- * `Tempfile`
261
- * `StringIO`
262
- * `ActionDispatch::Http::UploadedFile` (Rails form upload)
263
- * `Shrine::RackFile` ([`rack_file`][rack_file plugin] plugin)
264
- * `Shrine::DataFile` ([`data_uri`][data_uri plugin] plugin)
265
- * `Shrine::UploadedFile`
266
- * `Down::ChunkedIO` ([Down] gem)
275
+ * [`File`](https://ruby-doc.org/core/File.html)
276
+ * [`Tempfile`](https://ruby-doc.org/stdlib/libdoc/tempfile/rdoc/Tempfile.html)
277
+ * [`StringIO`](https://ruby-doc.org/stdlib/libdoc/stringio/rdoc/StringIO.html)
278
+ * [`ActionDispatch::Http::UploadedFile`](https://api.rubyonrails.org/classes/ActionDispatch/Http/UploadedFile.html)
279
+ * [`Shrine::RackFile`](https://shrinerb.com/docs/plugins/rack_file)
280
+ * [`Shrine::DataFile`](https://shrinerb.com/docs/plugins/data_uri)
281
+ * [`Shrine::UploadedFile`](#uploaded-file)
282
+ * [`Down::ChunkedIO`](https://github.com/janko/down#streaming)
267
283
  * ...
268
284
 
269
285
  ```rb
@@ -424,9 +440,9 @@ See [Using Attacher] guide for more details.
424
440
 
425
441
  ### Temporary storage
426
442
 
427
- Shrine uses temporary storage to support retaining uploaded files across form
428
- redisplays and [direct uploads]. But you can disable this behaviour, and have
429
- files go straight to permanent storage:
443
+ Shrine uses temporary storage to support [file validation][validation] and
444
+ [direct uploads]. If you don't need these features, you can tell Shrine to
445
+ upload files directly to permanent storage:
430
446
 
431
447
  ```rb
432
448
  Shrine.plugin :model, cache: false
@@ -446,7 +462,7 @@ attacher.file.storage_key #=> :store
446
462
 
447
463
  ## Plugin system
448
464
 
449
- By default Shrine comes with a small core which provides only the essential
465
+ By default, Shrine comes with a small core which provides only the essential
450
466
  functionality. All additional features are available via [plugins], which also
451
467
  ship with Shrine. This way you can choose exactly what and how much Shrine does
452
468
  for you, and you load the code only for features that you use.
@@ -469,6 +485,12 @@ If you want to extend Shrine functionality with custom behaviour, you can also
469
485
  [create your own plugin][Creating Plugins]. There are also additional [external
470
486
  plugins] created by others.
471
487
 
488
+ > NOTE: An uploader class will inherit a copy of current superclass' plugin
489
+ > options at the time of subclassing. This means you should *not* load
490
+ > additional plugins on a superclass after the subclass has already been
491
+ > created, because new options will not get applied to the subclass, which
492
+ > can result in errors.
493
+
472
494
  ## Metadata
473
495
 
474
496
  Shrine automatically extracts some basic file metadata and saves them to the
@@ -504,7 +526,7 @@ gem "marcel", "~> 0.3"
504
526
  Shrine.plugin :determine_mime_type, analyzer: :marcel
505
527
  ```
506
528
  ```rb
507
- photo = Photo.create(image: StringIO.new("<?php ... ?>"))
529
+ photo = Photo.new(image: StringIO.new("<?php ... ?>"))
508
530
  photo.image.mime_type #=> "application/x-php"
509
531
  ```
510
532
 
@@ -517,10 +539,10 @@ the [Extracting Metadata] guide for more details.
517
539
 
518
540
  ## Processing
519
541
 
520
- Shrine allows you to process attached files up front or on-the-fly. For
521
- example, if your app is accepting image uploads, you can generate a predefined
522
- set of of thumbnails when the image is attached to a record, or you can have
523
- thumbnails generated dynamically as they're needed.
542
+ Shrine allows you to process attached files both "eagerly" and "on-the-fly".
543
+ For example, if your app is accepting image uploads, you can generate a
544
+ predefined set of thumbnails when the image is attached to a record, or you
545
+ can have thumbnails generated dynamically as they're needed.
524
546
 
525
547
  For image processing, it's recommended to use the **[ImageProcessing]** gem,
526
548
  which is a high-level wrapper for processing with
@@ -530,17 +552,19 @@ which is a high-level wrapper for processing with
530
552
  $ brew install imagemagick vips
531
553
  ```
532
554
 
533
- ### Processing up front
555
+ ### Eager processing
534
556
 
535
- You can use the [`derivatives`][derivatives plugin] plugin to generate a set of
536
- pre-defined processed files:
557
+ We can use the [`derivatives`][derivatives plugin] plugin to generate a
558
+ pre-defined set of processed files (e.g. image thumbnails). We do this by
559
+ registering a derivatives processor block and then explicitly triggering
560
+ creation:
537
561
 
538
562
  ```rb
539
563
  # Gemfile
540
564
  gem "image_processing", "~> 1.8"
541
565
  ```
542
566
  ```rb
543
- Shrine.plugin :derivatives
567
+ Shrine.plugin :derivatives, create_on_promote: true
544
568
  ```
545
569
  ```rb
546
570
  require "image_processing/mini_magick"
@@ -559,32 +583,29 @@ end
559
583
  ```
560
584
  ```rb
561
585
  photo = Photo.new(image: file)
562
- photo.image_derivatives! # calls derivatives processor and uploads results
563
- photo.save
586
+ photo.save # automatically creates derivatives on promotion
564
587
  ```
565
588
 
566
- If you're allowing the attached file to be updated later on, in your update
567
- route make sure to trigger derivatives creation for new attachments:
589
+ You can then retrieve the URL of a processed derivative:
568
590
 
569
591
  ```rb
570
- photo.image_derivatives! if photo.image_changed?
592
+ photo.image_url(:large) #=> "https://s3.amazonaws.com/path/to/large.jpg"
571
593
  ```
572
594
 
573
- After the processed files are uploaded, their data is saved into the
574
- `<attachment>_data` column. You can then retrieve the derivatives as
575
- [`Shrine::UploadedFile`][uploaded file] objects:
595
+ The derivatives data is stored in the `<attachment>_data` column, and you can
596
+ retrieve them as [`Shrine::UploadedFile`][uploaded file] objects:
576
597
 
577
598
  ```rb
578
- photo.image(:large) #=> #<Shrine::UploadedFile ...>
579
- photo.image(:large).url #=> "/uploads/store/lg043.jpg"
580
- photo.image(:large).size #=> 5825949
581
- photo.image(:large).mime_type #=> "image/jpeg"
599
+ photo.image(:large) #=> #<Shrine::UploadedFile id="path/to/large.jpg" storage=:store metadata={...}>
600
+ photo.image(:large).url #=> "https://s3.amazonaws.com/path/to/large.jpg"
601
+ photo.image(:large).size #=> 5825949
602
+ photo.image(:large).mime_type #=> "image/jpeg"
582
603
  ```
583
604
 
584
- For more details, see the [`derivatives`][derivatives plugin] plugin
585
- documentation and the [File Processing] guide.
605
+ For more details, see the [File Processing] guide and the
606
+ [`derivatives`][derivatives plugin] plugin documentation.
586
607
 
587
- ### Processing on-the-fly
608
+ ### On-the-fly processing
588
609
 
589
610
  On-the-fly processing is provided by the
590
611
  [`derivation_endpoint`][derivation_endpoint plugin] plugin. To set it up, we
@@ -597,24 +618,28 @@ processing we want to perform:
597
618
  gem "image_processing", "~> 1.8"
598
619
  ```
599
620
  ```rb
600
- # config/initializers/shrine.rb (Rails)
621
+ # config/initializers/rails.rb (Rails)
622
+ # ...
623
+ Shrine.plugin :derivation_endpoint, secret_key: "<YOUR_SECRET_KEY>"
624
+ ```
625
+ ```rb
601
626
  require "image_processing/mini_magick"
602
627
 
603
- Shrine.plugin :derivation_endpoint,
604
- secret_key: "<YOUR SECRET KEY>",
605
- prefix: "derivations" # needs to match the mount point in routes
628
+ class ImageUploader < Shrine
629
+ plugin :derivation_endpoint, prefix: "derivations/image" # matches mount point
606
630
 
607
- Shrine.derivation :thumbnail do |file, width, height|
608
- ImageProcessing::MiniMagick
609
- .source(file)
610
- .resize_to_limit!(width.to_i, height.to_i)
631
+ derivation :thumbnail do |file, width, height|
632
+ ImageProcessing::MiniMagick
633
+ .source(file)
634
+ .resize_to_limit!(width.to_i, height.to_i)
635
+ end
611
636
  end
612
637
  ```
613
638
  ```rb
614
639
  # config/routes.rb (Rails)
615
640
  Rails.application.routes.draw do
616
641
  # ...
617
- mount Shrine.derivation_endpoint => "/derivations"
642
+ mount ImageUploader.derivation_endpoint => "/derivations/image"
618
643
  end
619
644
  ```
620
645
 
@@ -623,7 +648,7 @@ processing:
623
648
 
624
649
  ```rb
625
650
  photo.image.derivation_url(:thumbnail, 600, 400)
626
- #=> "/derivations/thumbnail/600/400/eyJpZCI6ImZvbyIsInN0b3JhZ2UiOiJzdG9yZSJ9?signature=..."
651
+ #=> "/derivations/image/thumbnail/600/400/eyJpZCI6ImZvbyIsInN0b3JhZ2UiOiJzdG9yZSJ9?signature=..."
627
652
  ```
628
653
 
629
654
  The on-the-fly processing feature is highly customizable, see the
@@ -661,36 +686,85 @@ For more details, see the [File Validation] guide and
661
686
 
662
687
  ## Location
663
688
 
664
- Shrine automatically generated random locations before uploading files. By
665
- default the hierarchy is flat, meaning all files are stored in the root
666
- directory of the storage. The [`pretty_location`][pretty_location plugin]
667
- plugin provides a good default hierarchy, but you can also override
668
- `#generate_location` with a custom implementation:
689
+ Shrine automatically generates random locations before uploading files. By
690
+ default, the hierarchy is flat, meaning all files are stored in the root
691
+ directory of the storage.
692
+
693
+ ```
694
+ 024d9fe83bf4fafb.jpg
695
+ 768a336bf54de219.jpg
696
+ adfaa363629f7fc5.png
697
+ ...
698
+ ```
699
+
700
+ The [`pretty_location`][pretty_location plugin] plugin provides a good default
701
+ hierarchy:
702
+
703
+ ```rb
704
+ Shrine.plugin :pretty_location
705
+ ```
706
+ ```
707
+ user/
708
+ 564/
709
+ avatar/
710
+ aa3e0cd715.jpg
711
+ thumb-493g82jf23.jpg
712
+ photo/
713
+ 123/
714
+ image/
715
+ 13f8a7bc18.png
716
+ thumb-9be62da67e.png
717
+ ...
718
+ ```
719
+
720
+ But you can also override `Shrine#generate_location` with a custom
721
+ implementation, for example:
669
722
 
670
723
  ```rb
671
724
  class ImageUploader < Shrine
672
725
  def generate_location(io, record: nil, derivative: nil, **)
673
- type = record.class.name.downcase if record
674
- style = derivative ? "thumbs" : "originals"
675
- name = super # the default unique identifier
726
+ return super unless record
676
727
 
677
- [type, style, name].compact.join("/")
728
+ table = record.class.table_name
729
+ id = record.id
730
+ prefix = derivative || "original"
731
+
732
+ "uploads/#{table}/#{id}/#{prefix}-#{super}"
678
733
  end
679
734
  end
680
735
  ```
681
736
  ```
682
737
  uploads/
683
738
  photos/
684
- originals/
685
- la98lda74j3g.jpg
686
- thumbs/
687
- 95kd8kafg80a.jpg
688
- ka8agiaf9gk4.jpg
739
+ 123/
740
+ original-afe929b8b4.jpg
741
+ small-ad61f25883.jpg
742
+ medium-41b75c42bb.jpg
743
+ large-73e67abe50.jpg
744
+ ...
689
745
  ```
690
746
 
691
- Note that there should always be a random component in the location, so that
692
- the ORM dirty tracking is detected properly. Inside `#generate_location` you
693
- can also access the extracted metadata through the `:metadata` option.
747
+ > There should always be a random component in the location, so that the ORM
748
+ dirty tracking is detected properly.
749
+
750
+ The `Shrine#generate_location` method contains a lot of useful context for the
751
+ upcoming upload:
752
+
753
+ ```rb
754
+ class ImageUploader < Shrine
755
+ def generate_location(io, record: nil, name: nil, derivative: nil, metadata: {}, **options)
756
+ storage_key #=> :cache, :store, ...
757
+ io #=> #<File>, #<Shrine::UploadedFile>, ...
758
+ record #=> #<Photo>, #<User>, ...
759
+ name #=> :image, :avatar, ...
760
+ derivative #=> :small, :medium, :large, ... (derivatives plugin)
761
+ metadata #=> { "filename" => "nature.jpg", "mime_type" => "image/jpeg", "size" => 18573, ... }
762
+ options #=> { ... other uploader options ... }
763
+
764
+ # ...
765
+ end
766
+ end
767
+ ```
694
768
 
695
769
  ## Direct uploads
696
770
 
@@ -725,7 +799,7 @@ Shrine.plugin :upload_endpoint
725
799
  # config/routes.rb (Rails)
726
800
  Rails.application.routes.draw do
727
801
  # ...
728
- mount ImageUploader.upload_endpoint(:cache) => "/images/upload" # POST /images/upload
802
+ mount Shrine.upload_endpoint(:cache) => "/upload" # POST /upload
729
803
  end
730
804
  ```
731
805
 
@@ -835,7 +909,7 @@ resumable uploads from scratch, it includes a complete JavaScript example
835
909
 
836
910
  ## Backgrounding
837
911
 
838
- The [`backgrounding`][backgrounding plugin] allows you to move file promotion
912
+ The [`backgrounding`][backgrounding plugin] plugin allows you to move file promotion
839
913
  and deletion into a background job, using the backgrounding library [of your
840
914
  choice][Backgrounding Libraries]:
841
915
 
@@ -852,7 +926,7 @@ end
852
926
  class PromoteJob
853
927
  include Sidekiq::Worker
854
928
 
855
- def perform(attacher_class, record_class, record.id, name, file_data)
929
+ def perform(attacher_class, record_class, record_id, name, file_data)
856
930
  attacher_class = Object.const_get(attacher_class)
857
931
  record = Object.const_get(record_class).find(record_id) # if using Active Record
858
932
 
@@ -896,6 +970,8 @@ s3 = Shrine.storages[:cache]
896
970
  s3.clear! { |object| object.last_modified < Time.now - 7*24*60*60 } # delete files older than 1 week
897
971
  ```
898
972
 
973
+ For S3, it may be easier and cheaper to use [S3 bucket lifecycle expiration rules](http://docs.aws.amazon.com/AmazonS3/latest/UG/lifecycle-configuration-bucket-no-versioning.html) instead.
974
+
899
975
  ## Logging
900
976
 
901
977
  The [`instrumentation`][instrumentation plugin] plugin sends and logs events for
@@ -946,7 +1022,6 @@ In tests you might want to tell Shrine to log only warnings:
946
1022
  Shrine.logger.level = Logger::WARN
947
1023
  ```
948
1024
 
949
- [Advantages of Shrine]: https://shrinerb.com/docs/advantages
950
1025
  [Creating Plugins]: https://shrinerb.com/docs/creating-plugins
951
1026
  [Creating Storages]: https://shrinerb.com/docs/creating-storages
952
1027
  [Direct Uploads to S3]: https://shrinerb.com/docs/direct-s3
@@ -957,24 +1032,19 @@ Shrine.logger.level = Logger::WARN
957
1032
  [Using Attacher]: https://shrinerb.com/docs/attacher
958
1033
  [FileSystem]: https://shrinerb.com/docs/storage/file-system
959
1034
  [S3]: https://shrinerb.com/docs/storage/s3
1035
+ [Memory]: https://shrinerb.com/docs/storage/memory
1036
+ [Testing with Shrine]: https://shrinerb.com/docs/testing
960
1037
  [`Shrine::UploadedFile`]: https://shrinerb.com/rdoc/classes/Shrine/UploadedFile/InstanceMethods.html
961
1038
 
962
1039
  [attacher]: #attacher
963
1040
  [attachment]: #attaching
964
- [backgrounding]: #backgrounding
965
1041
  [direct uploads]: #direct-uploads
966
1042
  [io abstraction]: #io-abstraction
967
1043
  [location]: #location
968
1044
  [metadata]: #metadata
969
- [up front]: #processing-up-front
970
- [on-the-fly]: #processing-on-the-fly
971
- [plugin system]: #plugin-system
972
- [simple upload]: #simple-direct-upload
973
1045
  [presigned upload]: #presigned-direct-upload
974
- [resumable upload]: #resumable-direct-upload
975
1046
  [storage]: #storage
976
1047
  [uploaded file]: #uploaded-file
977
- [uploading]: #uploading
978
1048
  [uploader]: #uploader
979
1049
  [validation]: #validation
980
1050
 
@@ -1042,3 +1112,4 @@ Shrine.logger.level = Logger::WARN
1042
1112
  [storages]: https://shrinerb.com/docs/external/extensions#storages
1043
1113
  [plugins]: https://shrinerb.com/plugins
1044
1114
  [external plugins]: https://shrinerb.com/docs/external/extensions#plugins
1115
+ [gin index]: https://www.postgresql.org/docs/current/datatype-json.html#JSON-INDEXING