1

I have a few enums in my project that will be reused across multiple models, and a few of which will have their own internal logic, and so I've implemented them as value objects (as described here @ section 5) but I can't seem to get ActiveRecord validations to work with them. The simplest example is the Person model with a Gender value object.

Migration:

# db/migrate/###_create_people.rb
class CreatePeople < ActiveRecord::Migration[5.2]
  def change
    create_table :people do |t|
      t.string :name
      t.integer :age
      t.integer :gender
    end
  end
end

Model:

# app/models/person.rb
class Person < ApplicationRecord
  validates :gender, presence: true
  enum gender: Enums::Gender::GENDERS

  def gender
    @gender ||= Enums::Gender.new(read_attribute(:gender))
  end
end

Value Object:

# app/models/enums/gender.rb
module Enums
  class Gender
    GENDERS = %w(female male other).freeze

    def initialize(gender)
      @gender = gender
    end

    def eql?(other)
      to_s.eql?(other.to_s)
    end

    def to_s
      @gender.to_s
    end
  end
end

The only problem is that despite the model being set to validate the presence of the gender attribute, it allows a Person to be saved with a gender of nil. I'm not sure why that is, so I'm not sure where to start trying to fix the problem.

2 Answers2

1

So I figured it out myself. Big thanks to benjessop whose suggestion didn't work, but did set me on the right train of thought.

validates :gender, numericality: { integer_only: true, greater_than_or_equal_to: 0, less_than: Enums::Gender::GENDERS.count }

I'll probably write a custom validation to implement that logic into several different value object enums. Thanks again for those that tried to help.

0

In your model file person.rb:

enum gender: Enums::Gender::GENDERS

But, In your model file gender.rb: the constant is GENDER

Change the line in person.rb to:

enum gender: Enums::Gender::GENDER

instead of

enum gender: Enums::Gender::GENDERS

  • That typo (which I've fixed in my original post) doesn't exist in my code, it was just an error I made when providing the examples here. So while you're right in that there's an error there, that's not what's causing the validation issue. – Brian Murphy Jul 11 '20 at 18:43