Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to store Enum value in ActiveRecord and convert to string for display

I am trying to figure out what is the best way to store an enum value in activerecord but convert it to a 'title' for display in an app.

I.E.

Review Enum:

UNREVIEWED = {:title => "Unreviewed", :name => "UNREVIEWED"}
REVIEWED = {:title => "Reviewed", :name => "REVIEWED"}
FLAGGED = {:title => "Flagged as inappropriate", :name => "FLAGGED"} 

So in java land I was used to storing the ENUMs name ie (REVIEWED) in the database and then converting that name into that actual enum on the server such that I could call helper methods on it, ie:

review = Review.valueOf(review)
review.title()

Is there something similar I can do in rails to accomplish this?

FYI we are trying to keep our app super small so if I can easily accomplish this or something similar without a GEM that would be great.

Any 'standard' way to do this, as I imagine I am not the first to struggle with this issue?

Thanks!

like image 608
lostintranslation Avatar asked Feb 16 '13 15:02

lostintranslation


People also ask

How do I convert an enum to a String?

There are two ways to convert an Enum to String in Java, first by using the name() method of Enum which is an implicit method and available to all Enum, and second by using toString() method.

Can enums hold strings?

No they cannot. They are limited to numeric values of the underlying enum type.

How does enum work in Rails?

An enum is an attribute where the values map to integers in the database and can be queried by name. Enums also give us the ability to change the state of the data very quickly. This makes it easy to use enums in Rails and saves a lot of time by providing dynamic methods.


2 Answers

ActiveRecord enums is the best way to go since it's a part of the framework (since version 4.1).

Its usage is quite simple:

Migration:

class AddEnumToMyModel < ActiveRecord::Migration
  def change
    add_column :my_model, :status, :integer, default: 0
  end
end

Model:

class MyModel < ActiveRecord::Base
  enum status: [:draft, :beta, :public]
end

Then use it a will:

MyModel.draft # gets all drafts
MyModel.last.draft? # checks if the last model is draft
MyModel.last.status # gets the string description of the status of my model

For mode information refer to documentation.

like image 117
alexs333 Avatar answered Sep 22 '22 17:09

alexs333


there are a lot of posts about this issue, i guess that this points to most of them: http://thinkinginrails.com/2010/04/using-enums-for-constants/

i think that this is an over engineered thing, that you don't need in a dynamically typed language like ruby.

just use strings!

you could then use that like:

class Review < ActiveRecord::Base
  validates_inclusion_of :status, :in => ["UNREVIEWED", "REVIEWED", "FLAGGED"]
  def status
    read_attribute(:status)
  end
  def status= (value)
    write_attribute(:status, value)
  end
end
like image 20
phoet Avatar answered Sep 18 '22 17:09

phoet