ruby-on-railspostgresqlactiverecordaasm

ActiveRecord where query not working for attributes but select method is


What explains this bizarre behavior? work_state is an state attribute derived from aasm gem, but I don't have trouble querying this with other models...

MaintenanceOrder.all.select { |m| m.work_state == "pending_work" }.size
=> 235
MaintenanceOrder.all.pluck(:work_state).select { |s| s == "pending_work" }.size
=> 235
MaintenanceOrder.last.work_state
=> "pending_work"

# so at this point... obviously there are MaintenanceOrders with work_state of "pending_work", and yet...

MaintenanceOrder.where(work_state:"pending_work").size
=> 0

As requested, this is the state set up

aasm(:work, column: "work_state",no_direct_assignment: true )  do
    state :pending_work, initial: true
    state :in_progress
    state :complete
    state :not_fixable

What's further odd is that queries work with OTHER states, i.e., this works:

MaintenanceOrder.where(work_state:"in_progress").size
=> 12

Also the SQL looks fine when I do log_level = :debug

MaintenanceOrder.where(work_state:"pending_work").size
   (15.9ms)  SELECT COUNT(*) FROM "maintenance_orders"  WHERE "maintenance_orders"."work_state" = 'pending_work'
=> 0

Update on oddities.. is there a giant gotcha here that I don't know??? Another model has a SIMILAR issue. FWIW the states with issues, "pending_work" above and "pending_start" below both are the beginning, initial default states...

Item.where(aasm_state: "pending_start").size
=> 19 # so at least some records are found, but not all of them
Item.all.pluck(:aasm_state).select { |s| s == "pending_start" }.size
=> 19
Item.all.select { |i| i.aasm_state == "pending_start"}.size
=> 94

# If I delve a little deeper.... it appears that the where query is just picking up the last few records... even though there's no size limit indicated?? in other words

where_ids = Item.where(aasm_state: "pending_start").map(&:id).sort
select_ids = Item.all.select { |i| i.aasm_state == "pending_start"}.map { |i| i.id }.sort

where_ids == select_ids.last(19)
=> true

Solution

  • Ok I solved this... but wildly unsatisfactorily because it's just a plain mystery to me. The solution was different for the 2 different cases above. It seems like the root causes of the 2 were different, but it also seems like in neither case will I ever know the reason why...

    MaintenanceOrder model issue

    I did a lot of git diffs here to check my sanity. Literally... I turned config.log_level = :debug in production.rb then pushed the app to production. I monitored that the correct SQL statements were being used in the query (as I copied over into the above question). Then I reset config.log_level = :info and pushed to production. Then suddenly it worked.

    No other changes.. suddenly MaintenanceOrder.where(work_state:"pending_work").size returned the correct value

    Item model issue

    Here, the fact that the where query was finding some but not all records, and that the subset it was finding was only recent, made me wonder maaaaaybe the old records... were... saved... improperly somehow? I had after all just done a big database migration.

    So I ran Item.all.select {|i| i.aasm_state == "pending_start"}.each { |i| i.update_column(:aasm_state,"pending_start") }, and that fixed the problem