Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decoding Custom Types #133

Open
barnaclebarnes opened this issue Nov 16, 2022 · 1 comment
Open

Decoding Custom Types #133

barnaclebarnes opened this issue Nov 16, 2022 · 1 comment

Comments

@barnaclebarnes
Copy link

I have the following:

# app/models/attributes/content_versions.rb
class Attributes::ContentVersions
  include StoreModel::Model

  attribute :html, Base64Type.new
  attribute :xlsx, Base64Type.new
end
# app/types/base64_type.rb

class Base64Type < ActiveRecord::Type::Value
  def type
    :base64_string
  end

  def cast(value)
    return if value.blank?

    Base64.encode64(value)
  end
end
it "should return a summary of the content" do
      project = create(:project)
      project.content_summary.html = "<html></html>"
      expect(project.content_summary.html).to eq("<html></html>")
    end

Which gets:

       - <html></html>
       + PGh0bWw+PC9odG1sPg==\n

It seems that I can encode the values to the fields but cannot decode the values. I tried putting this in the base64_type.rb but that didn't seem to get called.

  def deserialize(value)
    return if value.blank?

    Base64.decode64(value)
  end

How do we override the deserialiser?

@DmitryTsepelev
Copy link
Owner

Hi @barnaclebarnes! Sorry it took me too long to respond 😞 The problem is that Rails (it's a Rails code, gem has nothing to do with it) uses cast/cast_value for both encoding and decoding so we have to do something like this:

class Base64Type < ActiveRecord::Type::Value
    def type
      :base64_string
    end

    def cast(value)
      return if value.blank?

      if base64?(value)
        Base64.decode64(value)
      else
        Base64.encode64(value)
      end
    end

    private

    def base64?(value)
      value.is_a?(String) && Base64.encode64(Base64.decode64(value)) == value
    end
  end

We do the same dirty hack in One implementation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants