Usage of Entity returns error undefined method `Entity'

Hello everyone ,
I am trying to find a way to use Shrine with a structure that wouldnt be linked to an Active Record model.
Column is good in serializing/deserializing. But I am now trying to use Entity in order to have an abstraction of the “image”.
I have created a special folder in my Rails app called “structures” and added this code :

class MyPhoto < Entity(:image_data)
  include MyUploader::Attachment(:image)
end

Shrine initializer does show Shrine.plugin :entity and MyUploader (names have been abstracted) has the following :

require "image_processing/vips"
require "image_processing/mini_magick"

class MyUploader < Shrine	

    	
   plugin :validation_helpers # to validate image data	
   plugin :add_metadata
   plugin :store_dimensions	
   plugin :derivatives
   plugin :default_storage, cache: :transfer_cache, store: :transfer_store
	
    etc ..

When I am creating a new entity instance MyPhoto.new I get error <main>': undefined method Entity’ for main:Object (NoMethodError)

I am not sure if I am usig Entity properly and was wondering if someone would have a Gist or thread about Entity ?
Thanks a lot

Hi Maxence,

The Entity in the examples was just supposed to be some imaginary class builder method, kind of like Struct. I realize now how it might be confusing, I’ve pushed a commit that replaces usage of Entity and Model in the docs with attr readers and accessors.

I would recommend using either dry-initializer or dry-struct for creating entity classes. dry-initializer is the simplest if you don’t need types:

require "dry/initializer"

class MyPhoto
  extend Dry::Initializer
  option :image_data, optional: true

  include MyUploader::Attachment(:image)
end

Hi Janko
Thanks a lot. It is working as expected now.

I can create a MyPhoto record and assign image_data to it.
(My image_data is what I get from S3 after a direct upload to “transfer test cache” with presign)

a = MyPhoto.new(image_data: {"id" => "s.jpg", "storage" => "transfer_test_cache", "metadata" => {"size" => "3600000" , "filename" =>"a.jpg", "mime_type" => "image/jpeg"}})

(well here I have manually uploaded a file called a.jpeg so it is not really a random id)

a.image.url returns a valid signed URL.

Though when I try to create derivatives I get error :
ImageProcessing::Error: either width or height must be specified

With ActiveRecord plugin width and height are set automatically.

Also I struggle a bit to validate and promote.

I tried with atomic helpers :
Shrine::Attacher.retrieve(
entity: MyPhoto,
name: :image,
file: {“id” => “a.jpg”, “storage” => “transfer_test_cache”})

but get error “Shrine::AttachmentChanged: attachment has changed” (also as per said above the image is indeed there and can be passed to “image_data” of MyPhoto instance and generate a valid signed URL).

I have been thinking I should pass my image details to image instead of image_data (of MyPhoto instance) as image_data seems more like a output than in input.
But I am not sure if I should create a specific option ‘image’ to my initializer and this will be understood as such by Shrine.

I think for the moment I will stick to Active Record plugin and create a table that I will clean with a background job (I am building an API and just need to return a JSON of *_data column, I don’t really mind having a table that I clean often).

I am a bit noob with Ruby :sweat_smile: to make everything work outside Activerecord plugin but if you have a few directions I will try further.