CodeSmith
CodeSmith

Reputation: 2233

Most Efficient Way to get the "id" of the first record in Rails

I'm reviewing some code and I came across a line that does the following:

Person.find_by(name: "Tom").id

The above code gets the FIRST record with a name of "Tom", then builds a model, then gets the id of that model. Since we only want the id, the process of retreiving all data in the model and initializing the model is unneeded. What's the best way to optimize this using active record queries?

I'd like to avoid a raw sql solution. So far I have been able to come up with:

Person.where(name: "Tom").pluck(:id).first

This is faster in some situations since pluck doesn't build the actual model object and doesn't load all the data. However, pluck is going to build an array of records with name "Tom", whereas the original statement only ever returns a single object or nil - so this technique could potentially be worse depending on the where statement. I'd like to avoid the array creation and potential for having a very long list of ids returned from the server. I could add a limit(1) in the chain,

Person.where(name: "Tom").limit(1).pluck(:id).first

but is seems like I'm making this more complicated than it should be.

Upvotes: 4

Views: 3050

Answers (3)

ccorey
ccorey

Reputation: 3

This might work depending on what you're looking for.

Person.where(name: "Tom").minimum(:id)
Person.where(name: "Tom").maximum(:id)

These will sort by id value while the Person.where(name: "Tom").first.id will sort off of your default sort. Which could be id, created_at, or primary_key.

eitherway test and see if it works for you

Upvotes: 0

Pioz
Pioz

Reputation: 6321

With Rails 6 you can use the new pick method:

Person.where(name: 'Tom').pick(:id)

Upvotes: 4

Jeremy Baker
Jeremy Baker

Reputation: 4272

This is a little verbose, but you can use select_value from the ActiveRecord connection like this:

Person.connection.select_value(Person.select(:id).where(name: 'Tom').limit(1))

Upvotes: 1

Related Questions