nathan
nathan

Reputation: 1506

Rails ActiveRecord SQL Queries out of order

I'm implementing a sync method in my rails app, but my SQL queries are being executed in the wrong order, messing up the sync.

Basically, I'm sending new objects from the client app along with a timestamp of the last sync, then fetching anything that changed on the server since the timestamp. I then create the new objects from the client and save the timestamp after the new objects are created to exclude them from the next sync.

def sync(new_obj_hashes, last_sync)
  updated_items = Item.where(user_id: user_id).where("updated_at > ?", last_sync)

  new_obj_hashes.each |obj_hash|
    Item.new(obj_hash).save!
  end

  last_sync = Time.now
end

The problem: From my SQL logs

UPDATE "items" SET ...blah blah... WHERE "items"."id" = x
SELECT "items".* FROM "items" WHERE "items"."user_id" = y AND (updated_at > z)

It's creating the new objects first and then fetching the updated objects, which means updated_items (which I send back to the client app) contains all the objects the client sent as well.

How do I get the SELECT statement to happen before the UPDATE?

Upvotes: 1

Views: 123

Answers (1)

Frederick Cheung
Frederick Cheung

Reputation: 84182

updated_items = Item.where(user_id: user_id).where("updated_at > ?", last_sync)

doesn't execute a SQL statement. It creates an ActiveRecord::Relation object which will execute itself when you call a method on it requiring this (for example all or most methods from Enumerable.

In your case sounds like you want to do

updated_items = Item.where(user_id: user_id).where("updated_at > ?", last_sync).all

so that the query is evaluated then rather than when you next use updated_items

Upvotes: 1

Related Questions