1

I have two models, one is Repository the second is Photo. A repository can have many photo's.

My end goal is to show a set of repositories and a display picture for each repository.

I want to do something like:

@repositories = Repository.limit(10)
repositories_id = @repositories.map &:id
@photos = Photos.where(repository_id: repositories_id)

However this will return multiple photo objects with the same repository_id and I just want the first instance.

Tucker
  • 659
  • 4
  • 16

1 Answers1

2

The simplest way is to move your Photo lookup into the map. It won't be the most efficient query pattern, but on 10 Repositories, it'll be fine for a while.

@repositories = Repository.limit(10)
@photos = @repositories.map do |repository|
  Photo.where(repository_id: repository.id).first
end

Or if you set up Repository.has_many :photos,

@repositories = Repository.limit(10)
@photos = @repositories.map do |repository|
  repository.photos.first
end

Update with 3 queries instead of 11

@repositories = Repository.limit(10)
repository_ids = @repositories.map &:id
photo_ids = Photo.where(repository_id: repository_ids).group(:repository_id).minimum(:id)
photos = Photo.find(photo_ids.values)
Kristján
  • 18,165
  • 5
  • 50
  • 62
  • 1
    That will load 10 Photo objects from my Db. Individually. I don't want to hit my Db 10 times for this query. – Tucker Jun 27 '15 at 16:38
  • More efficient pattern added. I think you can do it in one query if you write it totally custom [using PARTITION or a subquery](https://stackoverflow.com/questions/3800551/select-first-row-in-each-group-by-group). – Kristján Jun 27 '15 at 16:46