From bc3b6ea461ee82a4c34877168fd498b81f12763c Mon Sep 17 00:00:00 2001 From: Kevin Deisz <kevin.deisz@gmail.com> Date: Tue, 29 May 2018 15:57:56 -0400 Subject: Reflection for attachments Add the ability to reflect on the attachments that have been defined using ActiveRecord::Reflection. --- activestorage/lib/active_storage/attached/macros.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'activestorage/lib') diff --git a/activestorage/lib/active_storage/attached/macros.rb b/activestorage/lib/active_storage/attached/macros.rb index f99cf35680..6ad9fc43d7 100644 --- a/activestorage/lib/active_storage/attached/macros.rb +++ b/activestorage/lib/active_storage/attached/macros.rb @@ -48,6 +48,12 @@ module ActiveStorage else before_destroy { public_send(name).detach } end + + ActiveRecord::Reflection.add_attachment_reflection( + self, + name, + ActiveRecord::Reflection.create(:has_one_attached, name, nil, { dependent: dependent }, self) + ) end # Specifies the relation between multiple attachments and the model. @@ -105,6 +111,12 @@ module ActiveStorage else before_destroy { public_send(name).detach } end + + ActiveRecord::Reflection.add_attachment_reflection( + self, + name, + ActiveRecord::Reflection.create(:has_many_attached, name, nil, { dependent: dependent }, self) + ) end end end -- cgit v1.2.3 From ce337d1757fdd01e5f496f741e33275a7440b9ac Mon Sep 17 00:00:00 2001 From: Kevin Deisz <kevin.deisz@gmail.com> Date: Thu, 31 May 2018 09:33:14 -0400 Subject: Move ActiveStorage reflection logic entirely into ActiveStorage --- activestorage/lib/active_storage/engine.rb | 9 ++++ activestorage/lib/active_storage/reflection.rb | 63 ++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 activestorage/lib/active_storage/reflection.rb (limited to 'activestorage/lib') diff --git a/activestorage/lib/active_storage/engine.rb b/activestorage/lib/active_storage/engine.rb index 99588cdd4b..519b9ae283 100644 --- a/activestorage/lib/active_storage/engine.rb +++ b/activestorage/lib/active_storage/engine.rb @@ -10,6 +10,8 @@ require "active_storage/previewer/video_previewer" require "active_storage/analyzer/image_analyzer" require "active_storage/analyzer/video_analyzer" +require "active_storage/reflection" + module ActiveStorage class Engine < Rails::Engine # :nodoc: isolate_namespace ActiveStorage @@ -95,5 +97,12 @@ module ActiveStorage end end end + + initializer "active_storage.reflection" do + ActiveSupport.on_load(:active_record) do + include Reflection::ActiveRecordExtensions + ActiveRecord::Reflection.singleton_class.prepend(Reflection::ReflectionExtension) + end + end end end diff --git a/activestorage/lib/active_storage/reflection.rb b/activestorage/lib/active_storage/reflection.rb new file mode 100644 index 0000000000..9074b20126 --- /dev/null +++ b/activestorage/lib/active_storage/reflection.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +module ActiveStorage + module Reflection + # Holds all the metadata about a has_one_attached attachment as it was + # specified in the Active Record class. + class HasOneAttachedReflection < ActiveRecord::Reflection::MacroReflection #:nodoc: + def macro + :has_one_attached + end + end + + # Holds all the metadata about a has_many_attached attachment as it was + # specified in the Active Record class. + class HasManyAttachedReflection < ActiveRecord::Reflection::MacroReflection #:nodoc: + def macro + :has_many_attached + end + end + + module ReflectionExtension + def reflection_class_for(macro) + case macro + when :has_one_attached + HasOneAttachedReflection + when :has_many_attached + HasManyAttachedReflection + else + super + end + end + + def add_attachment_reflection(ar, name, reflection) + ar.attachment_reflections.merge!(name.to_s => reflection) + end + end + + module ActiveRecordExtensions + extend ActiveSupport::Concern + + included do + class_attribute :attachment_reflections, instance_writer: false, default: {} + end + + module ClassMethods + # Returns an array of reflection objects for all the attachments in the + # class. + def reflect_on_all_attachments + attachment_reflections.values + end + + # Returns the reflection object for the named +attachment+. + # + # User.reflect_on_attachment(:avatar) + # # => the avatar reflection + # + def reflect_on_attachment(attachment) + attachment_reflections[attachment.to_s] + end + end + end + end +end -- cgit v1.2.3 From 6c7e6abfaad149da02dbec4e4f2bd62c5d68805f Mon Sep 17 00:00:00 2001 From: Kevin Deisz <kevin.deisz@gmail.com> Date: Thu, 31 May 2018 21:15:51 -0400 Subject: Ensure reflection_class_for is private --- activestorage/lib/active_storage/reflection.rb | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'activestorage/lib') diff --git a/activestorage/lib/active_storage/reflection.rb b/activestorage/lib/active_storage/reflection.rb index 9074b20126..04a1b20882 100644 --- a/activestorage/lib/active_storage/reflection.rb +++ b/activestorage/lib/active_storage/reflection.rb @@ -18,21 +18,22 @@ module ActiveStorage end end - module ReflectionExtension - def reflection_class_for(macro) - case macro - when :has_one_attached - HasOneAttachedReflection - when :has_many_attached - HasManyAttachedReflection - else - super - end - end - + module ReflectionExtension # :nodoc: def add_attachment_reflection(ar, name, reflection) ar.attachment_reflections.merge!(name.to_s => reflection) end + + private + def reflection_class_for(macro) + case macro + when :has_one_attached + HasOneAttachedReflection + when :has_many_attached + HasManyAttachedReflection + else + super + end + end end module ActiveRecordExtensions -- cgit v1.2.3