2

I have the following model

class Request < ActiveRecord::Base
    # Enumerables
    enum status: [:pending, :accepted, :completed]
end

and the migration looks like this:

class CreateRequests < ActiveRecord::Migration
    def change
        create_table :requests do |t|
            t.column    :status, :integer, default: 0, index: true
        end
    end
end

Simplified, for the sake for the question.

Now, everything about my Enums works fine.

@request.pending?
@request.accepted!
# And so on...

But when I do the following query:

Request.where(status: :accepted)

This is what my log shows:

SELECT "requests".* FROM "requests" WHERE "requests"."status" = NULL LIMIT 20 OFFSET 0

This is obviously wrong, because of the NULL. Now I know I could do this

Request.accepted

But the other way should work as well, as explained in the documentation.

What is happening??

Enrique Moreno Tent
  • 24,127
  • 34
  • 104
  • 189

2 Answers2

1

try this

accepted_requests = Request.accepted

reference: In Rails 4.1, how to find records by enum symbol?

Community
  • 1
  • 1
Athar
  • 3,258
  • 1
  • 11
  • 16
  • In that case, the log says: `SELECT "requests".* FROM "requests" WHERE "requests"."status" = ? LIMIT 20 OFFSET 0 [["status", 1]]` which I guess it is correct, but the other way should work as well, no? – Enrique Moreno Tent Jul 29 '15 at 18:10
  • no this link http://edgeapi.rubyonrails.org/classes/ActiveRecord/Enum.html explains the reason. and i quote: `Note that when an Array is used, the implicit mapping from the values to database integers is derived from the order the values appear in the array. In the example, :active is mapped to 0 as it's the first element, and :archived is mapped to 1. In general, the i-th element is mapped to i-1 in the database.`.. will this work `Request.where(status: [:accepted])` – Athar Jul 29 '15 at 18:13
  • major reason is bcoz they are mapped to integers in database not by value. so when you pass string to query on integer it wont work. read first line `Declare an enum attribute where the values map to integers in the database,` – Athar Jul 29 '15 at 18:16
  • But I declare the enum like in the documentation. And the documentation tries to do a where, exactly as I did it. So where is the difference? – Enrique Moreno Tent Jul 29 '15 at 18:20
  • yes but documentation does not say that you can query on Model with string as condition. actually enum first have to map the status you pass in array into the integer in the same order of array and based on that integer it query the table using that integer as the type of status in database is also integer not string. i guess you are missing the part of integer in table and string in query. moreover. that is why Enum provides you to call status as scope it self to make things easy – Athar Jul 29 '15 at 18:24
  • document said this `Record.statuses[:accepted]` this will return you the integer in your case 2 i think. now this you can use to query table.. – Athar Jul 29 '15 at 18:28
  • Actually, it does say it. Watch the 3rd yellow block in this link http://edgeapi.rubyonrails.org/classes/ActiveRecord/Enum.html – Enrique Moreno Tent Jul 29 '15 at 18:31
  • actually that is the thing that only `edgeapi.rubyonrails.org` is suggesting which i guess is wrong. this is the http://api.rubyonrails.org/v4.1.0/classes/ActiveRecord/Enum.html link to api docs which i also checked and nothing like this... also i read this article. and he explicitly said that it wont work https://hackhands.com/ruby-on-enums-queries-and-rails-4-1/ as it is expecting integer nor string – Athar Jul 29 '15 at 18:35
0

I just realized that the feature I was trying to use is not available because I have been reading the Edge version of the documentation, which is probably still not released. Dumb error.

Enrique Moreno Tent
  • 24,127
  • 34
  • 104
  • 189