David StevensonDavid Stevenson
Standup 4/26/2010: Ruby hack night with Sarah Mei
edit Posted by David Stevenson on Monday April 26, 2010 at 10:03AM

Interesting Things

  • Given a list of IDs, how do you find which ones are not in the database?
ids = [1,2,3,4,5,0]
missing_ids = ids - Model.find_all_by_id(ids).collect(&:id)
  • Sarah Mei is hosting a Ruby Hack Night at pivotal labs tomorrow at 7PM (Tues April 27th. 731 Market St Floor 3, San Francisco).
  • There is an android users group tomorrow. We don't know any more about it than that.

Comments

  1. WT WT on April 26, 2010 at 11:49PM

    You don't want to instantiate those objects. Wow.

    Use #select or use a method from ActiveRecord::ConnectionAdapters::DatabaseStatements.

    ids = [1,2,3,4444444] missing_ids = ids - Model.select(:id).where(id: ids).all.map(&:id)

  2. Sam Sam on April 27, 2010 at 04:05PM

    Yep, or pre r3:

    ids - Model.all(:conditions => {:id => ids}, :select => [:id]).collect(&:id)
    

    I thought that exists? might work for this, but you'd have to iterative over ids, generating loads more queries than you need. You can pass it conditions, but it will return a simple 'true' if ANY of the records have that ID.

  3. David Stevenson David Stevenson on April 28, 2010 at 10:33AM

    Regardless of WT or Sam's solution, you're still instantiating objects. Thanks for pointing out that we should only be brining back the IDs, however, that can be a big performance win. If you really only want the IDs and not objects, you'd have to write straight SQL (which isn't very rails friendly):

    ids - Model.connection.select_values("SELECT #{Model.primary_key} FROM #{Model.table_name} WHERE #{Model.primary_key} IN (#{ids.join(",")})").collect(&:to_i)

    The above statement doesn't use adapter-specific column or table name quoting, which would have made it even more generic for non-mysql adapters.

  4. Joseph Palermo Joseph Palermo on April 28, 2010 at 11:54PM

    Also, it wasn't stated originally, but there was an object caching layer (via cache money I think) that direct SQL access would have bypassed.

  5. fetion fetion on May 04, 2010 at 07:29PM

    You can pass it conditions, but it will return a simple 'true' if ANY of the records have that ID.

    remove