madeintandem / jsonb_accessor

Adds typed jsonb backed fields to your ActiveRecord models.
MIT License
1.11k stars 93 forks source link

Enum conversion/validation issue #146

Closed kg-currenxie closed 2 years ago

kg-currenxie commented 2 years ago

Hi.

Normal AR model + enum:

class Permission < ApplicationRecord
  enum permission: { hidden: 0, public: 1 }
  validates :permission, inclusion: { in: permissions.keys }
end

Test

=> Permission.first.update(permission: 'public')

  Permission Update (0.3ms)  UPDATE "permissions" SET "permission" = $1, "updated_at" = $2 WHERE "permissions"."id" = $3  [["permission", 1], ["updated_at", "2022-06-24 16:37:53.883109"], ["id", 3]]
  TRANSACTION (0.5ms)  COMMIT

Actual value in database column is the integer


With jsonb_accessor

class User < ApplicationRecord
  jsonb_accessor :settings, albums_permission: [:integer, default: 0]

  enum albums_permission: { hidden: 0, public: 1 }
  validates :albums_permission, inclusion: { in: albums_permissions.keys }
end

Test

=> User.first.update(albums_permission: 'public')

  TRANSACTION (0.1ms)  BEGIN
  User Update (0.5ms)  UPDATE "users" SET "settings" = $1, "updated_at" = $2 WHERE "users"."id" = $3  [["settings", "{\"albums_permission\":\"public\"}"], ["updated_at", "2022-06-24 16:42:56.234896"], ["id", 1]]
  TRANSACTION (0.7ms)  COMMIT

Actual value in the database is {"albums_permission": "public"} rather than {"albums_permission": 1}

Shouldn't the [:integer, default: 0] convert the enum string to integer before saving? 🤔 am i doing something wrong? or maybe is this expected behavior?

haffla commented 2 years ago

Hello @kg-currenxie,

jsonb_accessor doesn't do any automatic conversion of values.

jsonb_accessor :settings, albums_permission: [:integer, default: 0] simply creates an attribute albums_permission that defaults to 0 and tries to cast the value to an integer. I guess it would somehow be possible to make jsonb_accessor work nicely with Rails' enum but honestly I think this is quite the niche use case. But you are welcome to contribute to this repository and give it go.

kg-currenxie commented 2 years ago

Understood :) I'll switch to storing the string in the db instead