active_shrine 0.5.0 → 0.6.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 197975739ca00f2daa4c862413a372ee52ce634c308b6f5784d2b588d4f4e498
4
- data.tar.gz: 5d6119a5f5d32d54a79adff404fce302c2aa170b0b62edb09486b6d510732185
3
+ metadata.gz: 00f454741e3498d96b3e51fe4069a3710c1da4dbf029c7217894ffd917818240
4
+ data.tar.gz: 70521e166a1f473a7ee7c40262e985c4cff3ada4001fc736196be9d7877020c6
5
5
  SHA512:
6
- metadata.gz: cce39085bbe3593da28a9d845b9319343efead530dfd8177d62a4c3f9891cbdb771900772e7f4e561f31f5fe25def92eae07c237be3f6b547084093eecc68a3e
7
- data.tar.gz: 66ecf1b6c13c4f0420a3e1ae45a554620a73c3f67ca96c7bca2c0dd0e72afdcad103596f66cac72bd974291a9e7008a0465e175a560299517b3ce1f83a2c28d6
6
+ metadata.gz: 83b210e7d6ecca7c906211d508617bbdcb6d04731b7652c764c1e6542cf5f75a71617301d50e339cafdf09b4714fcb2a59a712ade97a7ab06c5526b1971733d3
7
+ data.tar.gz: 340885a2d58807f7a227c62f2e2142def6629dbdec4ac25959fff05ee941c044078ec0f3e4a4b93381d63236b4a7858f30e1662c95f83936639a20c6e86f7c3d
data/Appraisals ADDED
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ appraise "rails-7.1" do
4
+ gem "rails", "~> 7.1.3", ">= 7.1.3.4", "< 8.0.0"
5
+ gem "sqlite3", "~> 1.4"
6
+ end
7
+
8
+ appraise "rails-8" do
9
+ gem "rails", "~> 8.0.0"
10
+ gem "sqlite3", "~> 2.1"
11
+ end
data/README.md CHANGED
@@ -105,6 +105,64 @@ class User < ApplicationRecord
105
105
  end
106
106
  ```
107
107
 
108
+ ## Updating Polymorphic Associations
109
+
110
+ ActiveShrine uses polymorphic associations to link your models to their attachments. When you change an uploader for an existing attachment (for example, switching from the default `Shrine` uploader to a custom `ImageUploader`), you may need to update the polymorphic association data in existing records.
111
+
112
+ The attachment class names are stored in the `active_shrine_attachments` table in the `record_type` column. When you change uploaders, these class names need to be updated to maintain the correct associations.
113
+
114
+ ### Example Migration
115
+
116
+ If you previously had:
117
+
118
+ ```ruby
119
+ class User < ApplicationRecord
120
+ include ActiveShrine::Model
121
+
122
+ has_one_attached :avatar # Uses default Shrine uploader
123
+ end
124
+ ```
125
+
126
+ And you're changing to:
127
+
128
+ ```ruby
129
+ class User < ApplicationRecord
130
+ include ActiveShrine::Model
131
+
132
+ has_one_attached :avatar, uploader: ::ImageUploader
133
+ end
134
+ ```
135
+
136
+ You'll need to create a migration to update existing attachment records:
137
+
138
+ ```ruby
139
+ class UpdateAvatarAttachmentClasses < ActiveRecord::Migration[7.0]
140
+ def up
141
+ # Update existing avatar attachments to use the new ImageUploader attachment class
142
+ ActiveShrine::Attachment
143
+ .where(name: 'avatar', record_type: 'User')
144
+ .update_all(record_type: 'ActiveShrine::ImageUploaderAttachment')
145
+ end
146
+ end
147
+ ```
148
+
149
+ ### Important Notes
150
+
151
+ - **Backup First**: Always backup your database before running these migrations
152
+ - **Test Thoroughly**: Test the migration on a copy of your production data first
153
+ - **Class Names**: The attachment class names follow the pattern `ActiveShrine::{UploaderName}Attachment`
154
+
155
+ ### Verifying the Update
156
+
157
+ After running the migration, you can verify that your attachments are working correctly:
158
+
159
+ ```ruby
160
+ # Your existing attachments should continue to work
161
+ user = User.find(1)
162
+ user.avatar.url # Should work correctly with the new uploader
163
+ user.avatar.class # Should be ActiveShrine::ImageUploaderAttachment
164
+ ```
165
+
108
166
  ## Development
109
167
 
110
168
  After checking out the repo:
data/Rakefile CHANGED
@@ -1,4 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "bundler/gem_tasks"
4
- task default: %i[]
4
+ require "rake/testtask"
5
+ require "standard/rake"
6
+ require "appraisal"
7
+
8
+ task default: %i[test standard]
9
+
10
+ # https://juincc.medium.com/how-to-setup-minitest-for-your-gems-development-f29c4bee13c2
11
+ Rake::TestTask.new do |t|
12
+ t.libs << "test"
13
+ t.test_files = FileList["test/**/*_test.rb"]
14
+ t.verbose = true
15
+ end
16
+
17
+ Rake::TestTask.new(:test) do |t|
18
+ t.libs << "test"
19
+ t.libs << "lib"
20
+ t.test_files = FileList["test/**/*_test.rb"]
21
+ end
22
+
23
+ desc "Run tests across all appraisals"
24
+ task :test_all do
25
+ sh "bundle exec appraisal install"
26
+ sh "bundle exec appraisal test"
27
+ end
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rails", "~> 7.1.3", ">= 7.1.3.4", "< 8.0.0"
6
+ gem "sqlite3", "~> 1.4"
7
+
8
+ gemspec path: "../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rails", "~> 8.0.0"
6
+ gem "sqlite3", "~> 2.1"
7
+
8
+ gemspec path: "../"
@@ -27,7 +27,7 @@ module ActiveShrine
27
27
  attachment.errors.each do |error|
28
28
  record.errors.add(name, error.message)
29
29
  end
30
-
30
+
31
31
  raise ActiveRecord::RecordInvalid.new(record)
32
32
  end
33
33
 
@@ -81,7 +81,7 @@ module ActiveShrine
81
81
  end
82
82
  end
83
83
 
84
- super(value)
84
+ super
85
85
  rescue ActiveSupport::MessageVerifier::InvalidSignature
86
86
  errors.add(:file, "is invalid")
87
87
  end
@@ -101,10 +101,10 @@ module ActiveShrine
101
101
  end
102
102
 
103
103
  private
104
-
104
+
105
105
  def maybe_store_record
106
106
  return unless record.present?
107
-
107
+
108
108
  metadata.merge! record_type:, record_id:
109
109
  end
110
110
  end
@@ -7,7 +7,8 @@ module ActiveShrine
7
7
  module DestroyShrineAttachment
8
8
  private
9
9
 
10
- def perform(attacher_class, data)
10
+ def perform(attacher_class, record_class, data)
11
+ record_class.constantize # materialize the uploader polymorphic class
11
12
  attacher_class = attacher_class.constantize
12
13
 
13
14
  attacher = attacher_class.from_data(data)
@@ -7,11 +7,10 @@ module ActiveShrine
7
7
  module PromoteShrineAttachment
8
8
  private
9
9
 
10
- def perform(attacher_class, record_class, record_id, name, file_data)
11
- attacher_class = attacher_class.constantize
12
- record = record_class.constantize.find(record_id)
13
-
14
- attacher = attacher_class.retrieve(model: record, name:, file: file_data)
10
+ def perform(attacher_class, attachment_record_class, attachment_record_id, record_class, attribute_name, file_data)
11
+ record_class.constantize # materialize the uploader polymorphic class
12
+ attachment_record = attachment_record_class.constantize.find(attachment_record_id)
13
+ attacher = attacher_class.constantize.retrieve(model: attachment_record, name: attribute_name, file: file_data)
15
14
  attacher.atomic_promote
16
15
  rescue Shrine::AttachmentChanged, ActiveRecord::RecordNotFound
17
16
  # attachment has changed or record has been deleted, nothing to do
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveShrine
4
- VERSION = "0.5.0"
4
+ VERSION = "0.6.0"
5
5
  end
@@ -15,10 +15,6 @@ module ActiveShrine
15
15
  directory "app"
16
16
  directory "config"
17
17
  migration_template "db/migrate/create_active_shrine_attachments.rb", "db/migrate/create_active_shrine_attachments.rb"
18
-
19
- Bundler.with_unbundled_env do
20
- run "bundle add fastimage"
21
- end
22
18
  end
23
19
 
24
20
  def self.next_migration_number(dirname)
@@ -22,30 +22,20 @@ Shrine.plugin :determine_mime_type, analyzer: lambda { |io, analyzers|
22
22
  }
23
23
  Shrine.plugin :instrumentation
24
24
  Shrine.plugin :infer_extension, force: true
25
- Shrine.plugin :store_dimensions
25
+ # Shrine.plugin :store_dimensions # Requires the fastimage gem
26
26
  Shrine.plugin :pretty_location
27
27
  Shrine.plugin :refresh_metadata
28
28
 
29
29
  Shrine.plugin :backgrounding
30
30
 
31
31
  Shrine::Attacher.promote_block do
32
- if PromoteShrineAttachmentJob.respond_to? :perform_async
33
- # sidekiq
34
- PromoteShrineAttachmentJob.perform_async(self.class.name, record.class.name, record.id, name.to_s, file_data)
35
- else
36
- # activejob
37
- PromoteShrineAttachmentJob.perform_later(self.class.name, record.class.name, record.id, name.to_s, file_data)
38
- end
32
+ PromoteShrineAttachmentJob.perform_later(self.class.name, record.class.name, record.id, record.record_type, name.to_s, file_data)
39
33
  end
40
34
 
41
35
  Shrine::Attacher.destroy_block do
42
- if PromoteShrineAttachmentJob.respond_to? :perform_async
43
- # sidekiq
44
- DestroyShrineAttachmentJob.perform_async(self.class.name, data)
45
- else
46
- # activejob
47
- DestroyShrineAttachmentJob.perform_later(self.class.name, data)
48
- end
36
+ DestroyShrineAttachmentJob.perform_later(self.class.name, record.record_type, data)
49
37
  end
50
38
 
51
39
  Shrine.plugin :upload_endpoint, url: true
40
+ Shrine.plugin :derivatives, create_on_promote: true
41
+ Shrine.plugin :processing
@@ -19,7 +19,7 @@ class CreateActiveShrineAttachments < ActiveRecord::Migration[7.0]
19
19
 
20
20
  t.timestamps
21
21
  end
22
-
22
+
23
23
  add_index :active_shrine_attachments, :name
24
24
  if ActiveRecord::Base.connection.adapter_name.downcase.include?("postgresql")
25
25
  add_index :active_shrine_attachments, :file_data, using: :gin
@@ -31,12 +31,12 @@ class CreateActiveShrineAttachments < ActiveRecord::Migration[7.0]
31
31
  end
32
32
 
33
33
  private
34
-
34
+
35
35
  def primary_and_foreign_key_types
36
36
  config = Rails.configuration.generators
37
37
  setting = config.options[config.orm][:primary_key_type]
38
38
  primary_key_type = setting || :primary_key
39
39
  foreign_key_type = setting || :bigint
40
- [ primary_key_type, foreign_key_type ]
40
+ [primary_key_type, foreign_key_type]
41
41
  end
42
42
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_shrine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Radioactive Labs
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-03-04 00:00:00.000000000 Z
11
+ date: 2025-07-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -67,7 +67,49 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: rspec
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: minitest
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: minitest-reporters
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: standard
71
113
  requirement: !ruby/object:Gem::Requirement
72
114
  requirements:
73
115
  - - ">="
@@ -116,12 +158,15 @@ extra_rdoc_files: []
116
158
  files:
117
159
  - ".rspec"
118
160
  - ".ruby-version"
161
+ - Appraisals
119
162
  - CHANGELOG.md
120
163
  - CODE_OF_CONDUCT.md
121
164
  - LICENSE.txt
122
165
  - README.md
123
166
  - Rakefile
124
167
  - config.ru
168
+ - gemfiles/rails_7.1.gemfile
169
+ - gemfiles/rails_8.gemfile
125
170
  - lib/active_shrine.rb
126
171
  - lib/active_shrine/attached.rb
127
172
  - lib/active_shrine/attached/base.rb