Possibility of mapping enum values to string type instead of integer
As far as I know it's not possible with Active Record's built-in enum functionality. However, there are a few popular 3rd party gems that do this. The closest match to what comes with Active Record are probably enumerize and SimpleEnum.
However, if you're looking for something a little different, I'd recommend ClassyEnum (full disclosure: I wrote it). Here are some of my notes on the difference between enumerize and SimpleEnum vs ClassyEnum:
Class-less enums (enumerize, SimpleEnum) are great for simple use
cases where you just need a field to represent one of a fixed set of
values. The main issue I have with this solution is that it encourages
conditionals scattered throughout your models, controllers and views.
It's tempting to use these gems because they are the simplest to
implement, but the long term payoff just isn't there IMO for anything
but the simplest cases.ClassyEnum was designed to solve the problem of having scattered
conditional logic related to the different enums. You can still use it
for simple collections that don't have logic, but when you do need to
add logic (and you almost certainly will), you can push that into the
individual enum classes and take advantage of polymorphism.
How can I cast a enum string value to column type?
The cast
method casts a value from user input when it is assigned to an instance. In the case of enum
when you assign a string value it remains a string value. It is converted to an integer only when it is persisted in DB.
class Order < ActiveRecord::Base
enum status: {confirmed: 1, cancelled: 2}
end
# this is where the `cast` method is called
@order.status = "cancelled"
# still a string since the `cast` method didn't do anything.
@order.status # => "cancelled"
What you really need is the serialize
method. It casts a value from a ruby type to a type that the database knows how to understand.
Order.attribute_types["status"].serialize("cancelled") # => 2
How can I display enum string key instead of integer value in SQL query?
You are asking the DB for info using SQL and so it will not have any knowledge of your Rails enums. You need to use Rails to make the query:
Animals.all.group(:sound).count(:sound)
=> {"bark"=>2, "meow"=>4, "moo"=>3}
For a pure sql answer with Postgresql:
SELECT temp.sound_count,
CASE
when temp.sound = 0 then 'bark'
when temp.sound = 1 then 'meow'
when temp.sound = 2 then 'moo'
END
AS my_sound
FROM (SELECT COUNT(s.sound) as sound_count, a.sound from animals a
GOUP BY a.sound)
AS temp;
How do you use LIKE query for enum in rails?
Enums are normally stored as integers in the database. The mapping to a label is done on application level. The database is not aware of the labels.
This means you'll have to figure out what labels match your criteria on application level. Then convert them into their integer values (which are used in the database). One way to achieve this would be to use grep
in combination with a regex that matches your requirements.
# find the matching labels
labels = ConfirmedTask.task_statuses.keys.grep(/pend/i)
# convert them into their integer values
values = labels.map(&ConfirmedTask.task_statuses)
# create your query
ConfirmedTask.where('task_status IN (?)', values)
Somewhat easier would be to drop the label to value translation and let Rails figure this out. This can be done by passing the array of labels to a normal where
call (with a non-SQL string argument).
# find the matching labels
labels = ConfirmedTask.task_statuses.keys.grep(/pend/i)
# pass labels to `where` and let Rails do the label -> integer conversion
ConfirmedTask.where(task_status: labels)
I'm not 100% sure if an array of strings is allowed as the where
condition of an enum attribute. The documentation uses symbols. If the above does not work, map the strings into symbols with .map(&:to_sym)
.
Related Topics
Using Activerecord Interface for Models Backed by External API in Ruby on Rails
Is It a Bad Idea to Reload Routes Dynamically in Rails
How to Disable a Form Submit Button "A Là Ruby on Rails Way"
Implementing Bayesian Classifier in Ruby
Memorable Name Generator Gem for Ruby
Running Phantomjs from a Ruby on Rails Application
Ruby Amazon S3 Access Denied When Listing Buckets
Sequel Accessing Many_To_Many Join Table When Adding Association
Rails: Difference Between Env.Fetch() and Env[]
Sleep Until Condition Is True in Ruby
Mechanize How to Get Current Url
What Rails Plugins Are Good, Stable and *Really* Enhance Your Code
Should I Deploy My Ruby on Rails Application on Heroku
Ruby: How to Find Out If a Character Is a Letter or a Digit