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