开发者

constant enums in rails models and database

开发者 https://www.devze.com 2023-02-27 06:18 出处:网络
I want to find a clean way to maintain enumerations in both the database and model. Say I have an ActiveRecord class with a constant enumeration of types

I want to find a clean way to maintain enumerations in both the database and model.

Say I have an ActiveRecord class with a constant enumeration of types

class Foo < ActiveRecord::Base
   TYPES = {1 => :hello, 2 => :hi}
end

I've gone further and written an Enumeration class so I can do Foo::TYPES.HELLO to get 1, or Foo::TYPES.HI to get 2.

I want these types in the database so I can do joins. I'm currently creating a FooType model, and having Foo belongs_to :foo_type, so Foo will have a foo_type_id field.

class Foo < ActiveRecord::Base
   belongs_to :foo_type # 1 -> hello, 2 -> hi
end

However this is inconvenient because:

  • Test environments break unless I seed the test db every time. Types are ass开发者_如何学Cumed to be constant so they are directly used in code. This is probably the biggest pain
  • If I do a static enumeration pulling foo_type_ids from the db into the model, this also breaks in tests
  • If I add a new type, I have to reflect this in every database
  • Each environment needs to be seeded with types


I used the enumerated_attribute gem from https://github.com/jeffp/enumerated_attribute

This lets you define the enumeration and its values in the model. It's really designed to make dealing with them easier on the Rails / UI side (not so much database), but it will save you the hassles of maintaining a separate model for your enumeration and ensure consistency.

It will work in test environments, you won't need to update your DB when you add a new value and you won't need to seed the database. Just create a new column for the value of the enumeration and the gem does the rest. It stores the value as a string so it's pretty easy to manipulate from within the database if that's what you need.


Having enumerators in your code just make your code readable, nothing other than that. Rather than having an integer (which doesn't have readability for developers), you use come kind of String to represent that value

TYPES = {1 => :hello, 2 => :hi}

I dont think you can use AR relations like 'belongs_to' inside a normal class (non AR)

I think what you need is two tables

table -

foos
        id
        type
        foo_type_id 

foo_types
        id
        foo_type

then U can have the AR

class Foo  < ActiveRecord::Base
   belongs_to :foo_type
end 

class FooType  < ActiveRecord::Base
  has_many : foos
end

If you are going for DB solution (other than having static enumerators), you dont have an option but to add types to each env.

HTH

cheers

sameera

0

精彩评论

暂无评论...
验证码 换一张
取 消