Return ActiveRecord relation from WHERE NOT EXISTS query

478 views Asked by At

Okay so here's a fun one. The relations are something like:

A Client has_many state_changes, and a StateChange belongs_to one Client.

I have this query: Client.find_by_sql('SELECT * FROM clients cs WHERE NOT EXISTS (SELECT * FROM state_changes WHERE state_changes.client_id = cs.id AND current = true)')

The problem is that this returns an Array object and not an ActiveRecord Relation. I need to run an update on the state_changes that belong to the returned clients from that query.

So there's two issues essentially, getting the results as an ActiveRecord relation, and then getting all of their state_changes, also as an ActiveRecord relation, so that I can run the update.

I also understand that this might be a convoluted way to go about it...

1

There are 1 answers

3
Andrey Deineko On BEST ANSWER

I also understand that this might be a convoluted way to go about it..

Having easy AR interface - indeed it is convoluted :)

I would probably go with some scopes:

class StateChange
  scope :active, -> { where.not(current: false) }
  # I believe with your setup it is not equal to `where(current: true)`
end

class Client
  scope :some_smart_name, -> { includes(:state_changes).merge(StateChange.active) }
end

This should return you clients who who don't have associated state_changes with current set to false.