constant enums in rails models and database
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
精彩评论