2

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
james
  • 3,989
  • 8
  • 47
  • 102
  • Could you add the ``aasm`` definition from the model to your question? – rmlockerd Jul 27 '20 at 00:24
  • Maybe its a **Enum** field so pass the integer value with where query. – code_aks Jul 27 '20 at 03:02
  • @mlockerd posted – james Jul 27 '20 at 04:59
  • @code_aks alas it's not, in fact, other states are query-able – james Jul 27 '20 at 04:59
  • 2
    Just turn on `development` mode OR change log level to `config.log_level = :debug` to watch actual SQL generated for your console commands. Than inspect your DB. And you will get the answer. – Pavel Mikhailyuk Jul 27 '20 at 06:40
  • @PavelMikhailyuk how do I turn on `development` mode? is it possible for production heroku app's pg db? – james Jul 27 '20 at 18:12
  • I can't reproduce in any of my AASM models, which I realise isn't super helpful. If you are running a console via ``heroku run`` you ought to be able to run ``ActiveRecord::Base.logger.level = :debug`` to turn on SQL logging for that session. I'd also suggest running ``MaintenanceOrder.all.pluck(:work_state)`` to see if you have any suspect states in the database. – rmlockerd Jul 27 '20 at 21:08
  • @rmlockerd ok i added `pluck` results, SO WEIRD... in `MaintenanceOrder` where the `where` query returns nothing, `pluck` has same result as `select`. In the `Item` where the `where` query returns a partial set, `pluck` has same result as `where` (i.e., the partial set) – james Jul 28 '20 at 04:16
  • ``WHERE "maintenance_orders"."aasm_state" = 'pending_work'`` -- that's why you get 0 results; it is using ``aasm_state`` as the query column rather than ``work_state``. I don't understand that at all at the moment, but I think that's a big clue. – rmlockerd Jul 28 '20 at 04:53
  • @rmlockerd wait no sorry that's cuz i copied and typed wrong =/ – james Jul 28 '20 at 05:13

1 Answers1

0

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

james
  • 3,989
  • 8
  • 47
  • 102
  • I did a typo in my comment. **Then** inspect your DB. You had to do it to clear it all. For example, query like `Item.group(:aasm_state).count` could show you a lot of things like typos or NULLs in the `aasm_state` and so on. If you'd still have the strange things, you could go to DB directly through console client. – Pavel Mikhailyuk Jul 28 '20 at 07:22