module SycamoreStorage
  extend ActiveSupport::Concern

  included do
    has_many :sycamore_storage_attachments,
      foreign_key: :associated_id, as: :associated

    def self.has_many_attachments(name)
      has_options(:has_many, name)

      attachment = name.to_s.singularize

      define_method("#{attachment}=".to_sym) do |value|
        send(name).build(school: school).attach(value)
      end
    end

    private_class_method :has_many_attachments

    def self.has_one_attachment(name)
      has_options(:has_one, name)

      define_method("#{name}=".to_sym) do |value|
        find_or_build(name).attach(value)
      end
    end

    private_class_method :has_one_attachment

    def self.has_options(relationship, association)
      send relationship, association,
        -> { where(name: association) },
        class_name: 'SycamoreStorageAttachment',
        foreign_key: :associated_id,
        autosave: true,
        as: :associated
    end

    private_class_method :has_options
  end

  private
    def find_or_build(name)
      send(name) || send("build_#{name}", school: school)
    end
end
