database_consistency icon indicating copy to clipboard operation
database_consistency copied to clipboard

enum + validation consistency check

Open mpapis opened this issue 3 years ago • 4 comments

Hi :)

I've got quite few enum's in database and I've found few instances when the Rails enum was not set to include all DB enum values, this lead to reading the field as nil in case the value was missing in Rails enum.

Example:

  • schema: t.column "type", "enum('STONE','TREE')", default: "STONE"
  • model: enum type: { "STONE" => "STONE", "TREES" => "TREES"], _prefix: :type
  • validation: validate :type, inclusion: { in: %w[STONE TREES] } - actually if enum is synced then this can be smaller list, but still it can include something invalid for DB - like TREES - note the extra S.

Do you think it can make place into the gem?

mpapis avatar Oct 26 '21 10:10 mpapis

Hello Michal! Long time no see, how are you doing?

Do you think it can make place into the gem?

This suggestion is great for the gem as it maintains data consistency as well as better mapping between models and tables. Do you want to contribute with the check or I should?

djezzzl avatar Oct 26 '21 15:10 djezzzl

Hey guys! :wave:

I've realized I've crossed an enum-related issue just recently. It only happens when prepared_statements: option is set to false. This is typical and recommended by Rails when connecting via PgBouncer.

ActiveRecord::StatementInvalid: PG::UndefinedFunction: ERROR:  operator
   does not exist: text = integer
      LINE 1: SELECT "users".* FROM "users" WHERE "users"."os" = 0
# app/models/user.rb
enum os: [:linux, :windows]
# db/schema.rb
  t.text "os"

With prepared_statements: true this error doesn't happen, and it works as expected.

Should I file a separate issue?

pirj avatar Oct 28 '21 15:10 pirj

Filed https://github.com/djezzzl/database_consistency/issues/103 instead.

pirj avatar Oct 31 '21 18:10 pirj

@djezzzl please take care of it, I'm busy as usual ;) @pirj thanks, that's another use case I haven't thought of

I would distinct at least those use cases:

  • string enum in db & integer mapped enum in rails
  • integer in db & string mapped enum in rails
  • enum in db & string mapped enum in rails & different enums
  • enum in db & validation in rails with more fields then in db enum

probably there might be a lot of fun finding all edge cases like defaults or constrains

mpapis avatar Nov 02 '21 13:11 mpapis

Hi @mpapis,

Thank you for the suggestion! Sorry for taking it so long to be implemented. It was released in 1.6.0. Please let me know if that works for you.

djezzzl avatar Dec 03 '22 07:12 djezzzl