Apologies if the question is a little imprecise, but I'll describe my problem below.
I'm setting up some models in a Rails project, and one thing I've noticed I'm running into more than a few times is dealing with attributes that meet the following criteria:
For example, one of my models should have a status
field that can be set to one of: Defining, Executed, or Completed. I need to show those specific words within the interface, but I don't want to store the strings in the DB in case I need to change them in the future (or internationalize, or whatever.)
The obvious option is to define models for each of these models, but that seems to present a good deal of overhead in maintaining the models, ensuring that I write migrations between environments, etc. for each one of these, which seems like a lot of overhead.
The other option is to store it as an integer, and whip up an "enumeration" type class that stores the translation of those values - this would probably work fine, but I'm concerned that I'll lose associations and other handy stuff I get from ActiveRecord models.
Any advice on the best way to handle this situation?
Check out the ruby gem I've been working on called classy_enum. I'm pretty sure it does exactly what you're looking for. The README has some example usage, but the premise is that it lets you define multiple enum members as classes that can have different properties.
Define a varchar
or ENUM
in the database and validate the field in the model:
validates_inclusion_of :status, :in => %w(Defining Executed Completed)
Rails will treat it like a string field, but it still validates what the values are.
If you really need to abstract the text of the status field, you could just save it as an integer:
class Foo < ActiveRecord::Base
STATUS_DESCRIPTIONS = %w(Defining Executed Completed)
def status
STATUS_DESCRIPTIONS[ read_attribute(:status) ]
end
end
If it gets any more complicated than that, you should try @Beerlington's gem.
I was looking for a similar solution when I ran into the enumerize gem. I like its clean and simple DSL.
If your states contain a lot of state specific knowledge, then the state machine gen suggested by scaney might be a good idea. The other option is to use the good old state pattern with the state_pattern gem.
sounds like you might want a state_machine, see here: https://github.com/pluginaweek/state_machine
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With