In Rails 4.1, how to find records by enum symbol?
Solution 1
ActiveRecord::Enum
provides scopes based on its values.
Just try:
Conversation.active
or
Conversation.archived
Of course, you can create your own scopes as Kyle Decot mentioned.
Solution 2
This works great:
Conversation.where("conversation.status = ?", Conversation.statuses[:active])
For some reason this does NOT work:
Conversation.where(status: :active) #searches for NULL
Conversation.where(status: 'active') #searches for status=0 no matter what the enum
Update
All the above statements work with Rails 5. Happy coding!
Solution 3
ActiveRecord::Enum provides built-in scopes based on the values so you can simply do:
Conversation.active
Conversation.archived
Solution 4
Conversation.where(status: Conversation.statuses[:active])
Solution 5
Did you try Conversation.where(status: [:active, :archived])
?
As listed here.
Related videos on Youtube
Abdulaziz
Updated on March 01, 2020Comments
-
Abdulaziz about 4 years
Assume I have this model:
class Conversation < ActiveRecord::Base enum status: [ :active, :archived ] end
How can I find all active conversations without using the numeric value of the enum or without having to iterate over each conversation?
I tried doing
Conversation.where(status: :active)
, but it didn't yield any results.The only solution comes to mind is to iterate over all conversations and select the active ones, but it doesn't look like a good solution.
Conversation.all.select {|conversation| conversation.active? }
Is there anything I can do about this?
-
Waiting for Dev... almost 9 yearsIt will work in Rails 5 github.com/rails/rails/issues/19964
-
-
joshua.paling over 9 yearsNo need to create a new instance -
Conversation.statuses[:active]
should work -
Avael Kross about 9 yearsASAP, enum creates scopes like this by default, so if you have
enum status: %i[active archived]
, you already have.active
and.archived
scopes. -
pragma almost 9 yearsKensuke Naito's solution below is much better
-
Logar about 8 yearsThis one never worked for me. Everytime i have to match every record with the same state as my object I have to do
Conversation.where(status: Conversation.statuses[my_conversation.status])
. Any idea why it doesn't work ? -
Shifa Khan about 8 years@Logar Maybe isn't supposed to.. Check github.com/rails/rails/issues/19964
-
Logar about 8 yearsHehe, I got lured by documentation. At least now I know !
-
MegaTux about 8 yearsConversation.where(status: [Conversation.statuses[:active], Conversation.statuses[:archived]])
-
MegaTux about 8 yearsNice!, this way I can do "or" expressions: Conversation.where(status: [Conversation.statuses[:active], Conversation.statuses[:archived]])
-
Mirror318 almost 8 yearsNote that Rails 5 will allow all these statements to work. Woo!
-
Chris Nicola almost 8 yearsNot really a solution if you are passing that type value as a string say via an API request or query string value.
-
rubyprince about 7 yearsThe answer can be rewritten as
Conversation.where(status: Conversation.statuses[:active])
. No need for strings. -
Greg Blass almost 7 yearsJust switched back to work on a Rails 4 project and thought I was going nuts. Thank you for noting that these are Rails 5 conventions.
-
rmcsharry over 6 yearsAlso, if you wanted the opposite (ie. all records where status is anything other than active): Conversation.where.not(status: Conversation.statuses[:active])
-
Abe Voelker over 6 yearsUnfortunately Rails 5 doesn't fix querying through a parent (e.g.
Person.joins(:conversations).where(conversations: {status: :active})
errors out). Have to use the first method for that yet (Person.joins(:conversations).where(conversations: {status: Conversation.statuses[:active]})
).