botbot
botbot

Reputation: 7359

Find Value in Array of ActiveRecord Objects vs. Find Value from Repeated DB Calls

I would just like to return true, if my Array of Contact(s) (model) contains a Contact with id equal to some value. For example:

@contacts = Contact.all

@someval = "alskjdf"

find_val(@contacts, @someval)

def find_val(contacts, val)
  @contact.each do |c|
    if c.id == val
      return true
    end
  end
  return false
end

I have to do this repeatedly in my app (at most about 100 times for this particular actions), in order to exclude some data from an external API that has a list of contacts. Is this going to be too expensive?

I thought I might be able to do something faster, similar to ActiveRecord find on the array after it's been pulled down from the db, but can't figure that out. Would it be too expensive to call ActiveRecord like this?

Contacts.find_by_id(@someval)

The above line would have to be called hundreds of times... I figure iterating through the array would be less expensive. Thanks!

Upvotes: 1

Views: 532

Answers (2)

tlehman
tlehman

Reputation: 5167

One way to reduce the amount of code you have to write to search the array is to open the array class and make a custom instance method:

class Array
  def haz_value?(someval)
    if self.first.respond_to? :id
      self.select { |contact| contact.id == someval }.length > 0
    else
      false
    end
  end
end

Then, you can call @contacts.haz_value? @someval. In terms of efficiency, I haven't done a comparison, but both ways use Array's built-in iterators. It would probably be faster to create a stored procedure in your database and call it through ActiveRecord, here is how you can do that.

Upvotes: 1

alf
alf

Reputation: 18550

The best approach would be to index the contacts in a hash, using the contact id as the key after you retrieve them all from the db:

contacts = Contact.all.inject({}) {|hash, contact| hash[contact.id] = contact; hash }

Then you can easily get a contact with contact[id] in a performant way.

Upvotes: 2

Related Questions