It turns out I was trying to do things I had seen in various examples of modules. It was simple to get it working:
module WithImage
extend ActiveSupport::Concern
included do
attr_accessor :photo
has_one :medium, as: :imageable
after_save :find_or_create_medium, if: :photo?
def photo?
self.photo.present?
end
def find_or_create_medium
medium = Medium.find_or_initialize_by_imageable_id_and_imageable_type(self.id, self.class.to_s)
medium.attachment = photo
medium.save
end
def photo_url
medium.attachment.url if medium.present?
end
end
end