Home > Software engineering >  Rails 7 ActiveQuery select with EXISTS returns an object
Rails 7 ActiveQuery select with EXISTS returns an object

Time:08-03

Trying to run a query for a resource with an additional, computed value. I.e.

Model.where(id: 1)
     .select(
       'models.*', 
       'EXISTS(SELECT 1 FROM models WHERE models.id IS NOT NULL) AS computed_value'
      )

I would expect to receive the object, with an additional boolean field computed_value.

Instead, the computed_value is being returned as the first record for which the exists statement is true.

i.e.

[
 #<Model:<memory_address>
 column1: value,
 column2: value,
 computed_value: #<Model:<memory_address>
]

I'm now looking into other options, but what am I doing wrong here?

SOLVED: This was due to a naming collision. "computed_value" was already an integer column.

CodePudding user response:

I've tested your query on my database (Rails 7 as well) and seems it works as expected. You can find an example bellow

bookings = Booking.where(id: 1)
     .select(
       'bookings.id', 
       'EXISTS(SELECT 1 FROM bookings WHERE bookings.id IS NOT NULL) AS computed_value'
      )
2022-08-03 08:17:02.466963 D [60306:94480 log_subscriber.rb:130] ActiveRecord::Base --   Booking Load (0.6ms)  SELECT "bookings"."id", EXISTS(SELECT 1 FROM bookings WHERE bookings.id IS NOT NULL) AS computed_value FROM "bookings" WHERE "bookings"."id" = $1  [["id", 1]]

=> [#<Booking:0x00000001185a50a0 id: 1>]
[19] pry(main)> booking = bookings.first
=> #<Booking:0x00000001185a50a0 id: 1>
[20] pry(main)> booking.computed_value
=> true

What is strange is that you're getting the computed_value under collection response, which makes me think that you already have such field on the database or so. Aggregated fields shouldn't be visible as the AR collection doesn't know about them but they're accessible on demand.

  • Related