[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-7859":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":16,"stars7d":16,"stars30d":17,"stars90d":16,"forks30d":16,"starsTrendScore":16,"compositeScore":18,"rankGlobal":10,"rankLanguage":10,"license":19,"archived":20,"fork":20,"defaultBranch":21,"hasWiki":22,"hasPages":22,"topics":23,"createdAt":10,"pushedAt":10,"updatedAt":35,"readmeContent":36,"aiSummary":37,"trendingCount":16,"starSnapshotCount":16,"syncStatus":38,"lastSyncTime":39,"discoverSource":40},7859,"shrine","shrinerb\u002Fshrine","shrinerb","File Attachment toolkit for Ruby applications","https:\u002F\u002Fshrinerb.com",null,"Ruby",3277,276,35,8,0,5,29.33,"MIT License",false,"master",true,[24,25,26,27,28,29,30,31,32,33,34],"attachment","background-jobs","direct-upload","file-upload","filesystem","metadata","orm","rack","ruby","s3","storage","2026-06-12 02:01:45","# [Shrine]\n\n\u003Cimg src=\"https:\u002F\u002Fshrinerb.com\u002Fimg\u002Flogo.png\" width=\"100\" alt=\"Shrine logo: a red paperclip\" align=\"right\" \u002F>\n\nShrine is a toolkit for handling file attachments in Ruby applications. Some highlights:\n\n* **Modular design** – the [plugin system] allows you to load only the functionality you need\n* **Memory friendly** – streaming uploads and [downloads][Retrieving Uploads] make it work great with large files\n* **Cloud storage** – store files on [disk][FileSystem], [AWS S3][S3], [Google Cloud][GCS], [Cloudinary] and others\n* **Persistence integrations** – works with [Sequel], [ActiveRecord], [ROM], [Hanami] and [Mongoid] and others\n* **Flexible processing** – generate thumbnails [eagerly] or [on-the-fly] using [ImageMagick] or [libvips]\n* **Metadata validation** – [validate files][validation] based on [extracted metadata][metadata]\n* **Direct uploads** – upload asynchronously [to your app][simple upload] or [to the cloud][presigned upload] using [Uppy]\n* **Resumable uploads** – make large file uploads [resumable][resumable upload] on [S3][uppy-s3_multipart] or [tus][tus-ruby-server]\n* **Background jobs** – built-in support for [background processing][backgrounding] that supports [any backgrounding library][Backgrounding Libraries]\n\nIf you're curious how it compares to other file attachment libraries, see the\n[Advantages of Shrine]. Otherwise, follow along with the **[Getting Started\nguide]**.\n\n## Links\n\n| Resource                   | URL                                                                                      |\n| :----------------          | :-----------------------------------------------------------------------------           |\n| Website & Documentation    | [shrinerb.com](https:\u002F\u002Fshrinerb.com)                                                     |\n| Demo code                  | [Roda][roda demo] \u002F [Rails][rails demo]                                                  |\n| Wiki                       | [github.com\u002Fshrinerb\u002Fshrine\u002Fwiki](https:\u002F\u002Fgithub.com\u002Fshrinerb\u002Fshrine\u002Fwiki)               |\n| Discussion forum           | [github.com\u002Fshrinerb\u002Fshrine\u002Fdiscussions](https:\u002F\u002Fgithub.com\u002Fshrinerb\u002Fshrine\u002Fdiscussions) |\n| Alternate Discussion forum | [discourse.shrinerb.com](https:\u002F\u002Fdiscourse.shrinerb.com)                                 |\n\n## Setup\n\nRun:\n\n```sh\nbundle add shrine\n```\n\nThen add `config\u002Finitializers\u002Fshrine.rb` which sets up the storage and loads\nORM integration:\n\n```rb\nrequire \"shrine\"\nrequire \"shrine\u002Fstorage\u002Ffile_system\"\n\nShrine.storages = {\n  cache: Shrine::Storage::FileSystem.new(\"public\", prefix: \"uploads\u002Fcache\"), # temporary\n  store: Shrine::Storage::FileSystem.new(\"public\", prefix: \"uploads\"),       # permanent\n}\n\nShrine.plugin :activerecord           # loads Active Record integration\nShrine.plugin :cached_attachment_data # enables retaining cached file across form redisplays\nShrine.plugin :restore_cached_data    # extracts metadata for assigned cached files\n```\n\nNext, add the `\u003Cname>_data` column to the table you want to attach files to. For\nan \"image\" attachment on a `photos` table this would be an `image_data` column:\n\n```\n$ rails generate migration add_image_data_to_photos image_data:text # or :jsonb\n```\nIf using `jsonb` consider adding a [gin index] for fast key-value pair searchability within `image_data`.\n\nNow create an uploader class (which you can put in `app\u002Fuploaders`) and\nregister the attachment on your model:\n\n```rb\nclass ImageUploader \u003C Shrine\n  # plugins and uploading logic\nend\n```\n```rb\nclass Photo \u003C ActiveRecord::Base\n  include ImageUploader::Attachment(:image) # adds an `image` virtual attribute\nend\n```\n\nIn our views let's now add form fields for our attachment attribute that will\nallow users to upload files:\n\n```erb\n\u003C%= form_for @photo do |f| %>\n  \u003C%= f.hidden_field :image, value: @photo.cached_image_data, id: nil %>\n  \u003C%= f.file_field :image %>\n  \u003C%= f.submit %>\n\u003C% end %>\n```\n\nWhen the form is submitted, in your controller you can assign the file from\nrequest params to the attachment attribute on the model:\n\n```rb\nclass PhotosController \u003C ApplicationController\n  def create\n    Photo.create(photo_params) # attaches the uploaded file\n    # ...\n  end\n\n  private\n\n  def photo_params\n    params.require(:photo).permit(:image)\n  end\nend\n```\n\nOnce a file is uploaded and attached to the record, you can retrieve the file\nURL and display it on the page:\n\n```erb\n\u003C%= image_tag @photo.image_url %>\n```\n\nSee the **[Getting Started guide]** for further documentation.\n\n## Inspiration\n\nShrine was heavily inspired by [Refile] and [Roda]. From Refile it borrows the\nidea of \"backends\" (here named \"storages\"), attachment interface, and direct\nuploads. From Roda it borrows the implementation of an extensible plugin\nsystem.\n\n## Similar libraries\n\n* Paperclip\n* CarrierWave\n* Dragonfly\n* Refile\n* Active Storage\n\n## Contributing\n\nPlease refer to the [contributing page][Contributing].\n\n## Code of Conduct\n\nEveryone interacting in the Shrine project’s codebases, issue trackers, and\nmailing lists is expected to follow the [Shrine code of conduct][CoC].\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License].\n\n[Shrine]: https:\u002F\u002Fshrinerb.com\n[Advantages of Shrine]: https:\u002F\u002Fshrinerb.com\u002Fdocs\u002Fadvantages\n[plugin system]: https:\u002F\u002Fshrinerb.com\u002Fdocs\u002Fgetting-started#plugin-system\n[Retrieving Uploads]: https:\u002F\u002Fshrinerb.com\u002Fdocs\u002Fretrieving-uploads\n[FileSystem]: https:\u002F\u002Fshrinerb.com\u002Fdocs\u002Fstorage\u002Ffile-system\n[S3]: https:\u002F\u002Fshrinerb.com\u002Fdocs\u002Fstorage\u002Fs3\n[GCS]: https:\u002F\u002Fgithub.com\u002Frenchap\u002Fshrine-google_cloud_storage\n[Cloudinary]: https:\u002F\u002Fgithub.com\u002Fshrinerb\u002Fshrine-cloudinary\n[Sequel]: https:\u002F\u002Fshrinerb.com\u002Fdocs\u002Fplugins\u002Fsequel\n[ActiveRecord]: https:\u002F\u002Fshrinerb.com\u002Fdocs\u002Fplugins\u002Factiverecord\n[ROM]: https:\u002F\u002Fgithub.com\u002Fshrinerb\u002Fshrine-rom\n[Hanami]: https:\u002F\u002Fgithub.com\u002Fkatafrakt\u002Fhanami-shrine\n[Mongoid]: https:\u002F\u002Fgithub.com\u002Fshrinerb\u002Fshrine-mongoid\n[eagerly]: https:\u002F\u002Fshrinerb.com\u002Fdocs\u002Fgetting-started#eager-processing\n[on-the-fly]: https:\u002F\u002Fshrinerb.com\u002Fdocs\u002Fgetting-started#on-the-fly-processing\n[ImageMagick]: https:\u002F\u002Fgithub.com\u002Fjanko\u002Fimage_processing\u002Fblob\u002Fmaster\u002Fdoc\u002Fminimagick.md#readme\n[libvips]: https:\u002F\u002Fgithub.com\u002Fjanko\u002Fimage_processing\u002Fblob\u002Fmaster\u002Fdoc\u002Fvips.md#readme\n[validation]: https:\u002F\u002Fshrinerb.com\u002Fdocs\u002Fvalidation\n[metadata]: https:\u002F\u002Fshrinerb.com\u002Fdocs\u002Fmetadata\n[simple upload]: https:\u002F\u002Fshrinerb.com\u002Fdocs\u002Fgetting-started#simple-direct-upload\n[presigned upload]: https:\u002F\u002Fshrinerb.com\u002Fdocs\u002Fgetting-started#presigned-direct-upload\n[resumable upload]: https:\u002F\u002Fshrinerb.com\u002Fdocs\u002Fgetting-started#resumable-direct-upload\n[Uppy]: https:\u002F\u002Fuppy.io\u002F\n[uppy-s3_multipart]: https:\u002F\u002Fgithub.com\u002Fjanko\u002Fuppy-s3_multipart\n[tus-ruby-server]: https:\u002F\u002Fgithub.com\u002Fjanko\u002Ftus-ruby-server\n[backgrounding]: https:\u002F\u002Fshrinerb.com\u002Fdocs\u002Fplugins\u002Fbackgrounding\n[Backgrounding Libraries]: https:\u002F\u002Fgithub.com\u002Fshrinerb\u002Fshrine\u002Fwiki\u002FBackgrounding-Libraries\n[Getting Started guide]: https:\u002F\u002Fshrinerb.com\u002Fdocs\u002Fgetting-started\n[roda demo]: \u002Fdemo\n[rails demo]: https:\u002F\u002Fgithub.com\u002Ferikdahlstrand\u002Fshrine-rails-example\n[Refile]: https:\u002F\u002Fgithub.com\u002Frefile\u002Frefile\n[Roda]: https:\u002F\u002Fgithub.com\u002Fjeremyevans\u002Froda\n[CoC]: \u002FCODE_OF_CONDUCT.md\n[MIT License]: \u002FLICENSE.txt\n[Contributing]: https:\u002F\u002Fgithub.com\u002Fshrinerb\u002Fshrine\u002Fblob\u002Fmaster\u002FCONTRIBUTING.md\n[gin index]: https:\u002F\u002Fwww.postgresql.org\u002Fdocs\u002Fcurrent\u002Fdatatype-json.html#JSON-INDEXING\n","Shrine 是一个用于处理 Ruby 应用程序中文件附件的工具包。它采用模块化设计，通过插件系统加载所需功能，支持流式上传和下载以高效处理大文件，并能与多种云存储服务（如 AWS S3、Google Cloud）集成。Shrine 还提供对 Sequel、ActiveRecord 等持久化框架的支持，以及灵活的图片处理选项。此外，它支持直接上传、断点续传及后台任务处理等功能。适用于需要强大文件管理和处理能力的各种 Web 应用场景，尤其是那些涉及大量用户生成内容或媒体文件的应用。",2,"2026-06-11 03:14:46","top_language"]