Class: Tapioca::Dsl::Compilers::Paperclip

Inherits:
Tapioca::Dsl::Compiler
  • Object
show all
Extended by:
T::Sig
Includes:
RBIHelper
Defined in:
lib/tapioca/dsl/compilers/paperclip.rb

Overview

‘Tapioca::Dsl::Compilers::Paperclip` decorates RBI files for classes that use the `has_attached_file` method provided by the `paperclip` gem. github.com/thoughtbot/paperclip

For example, with the following ActiveRecord model: ~~~rb class Product < ActiveRecord::Base

has_attached_file(:marketing_image)

end ~~~

This compiler will generate the following RBI: ~~~rbi class Product

include PaperclipGeneratedMethods

module PaperclipGeneratedMethods
  sig { returns(::Paperclip::Attachment) }
  def marketing_image; end

  sig { params(value: T.untyped).void }
  def marketing_image=(value); end
end

end ~~~

Constant Summary collapse

InstanceModuleName =
"PaperclipGeneratedMethods"
ConstantType =
type_member { { fixed: T.class_of(::Paperclip::Glue) } }

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.gather_constantsObject



45
46
47
# File 'lib/tapioca/dsl/compilers/paperclip.rb', line 45

def gather_constants
  all_classes.select { |c| c < ::Paperclip::Glue }
end

Instance Method Details

#decorateObject



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/tapioca/dsl/compilers/paperclip.rb', line 51

def decorate
  # this is a bit awkward, but load order determines the return order here, so sort to ensure consistency across
  # all environments.
  attachments = ::Paperclip::AttachmentRegistry.names_for(constant).sort
  return if attachments.empty?

  root.create_path(constant) do |klass|
    instance_module = RBI::Module.new(InstanceModuleName)

    attachments.each do |attachment_name|
      # Model: has_attached_file(:marketing_image)
      # => marketing_image
      # => marketing_image=
      instance_module.create_method(attachment_name, return_type: "::Paperclip::Attachment")
      instance_module.create_method(
        "#{attachment_name}=",
        parameters: [create_param("value", type: "T.untyped")],
        return_type: nil,
      )
    end

    klass << instance_module
    klass.create_include(InstanceModuleName)
  end
end