2011-03-17 4 views
7

그래서 내 앱에는 컬렉션에 속한 사진이 있습니다. 한 페이지의 특정 컬렉션에서 13 장의 사진을 보여주고 싶습니다. 이 종류의 작품레일 : 특정 수의 임의의 레코드 얻기

c = Collection.first 
@photos = c.photos.offset(rand(c.photos.count)).limit(13) 

:

나는이 시도. 문제는 컬렉션에 13 장이 넘는 사진이 없으면 반드시 13 장의 사진을 반환하지 않는다는 것입니다. 구체적으로 정확히 13 장의 사진을 가져와야합니다.

FWIW 내 앱의 경우 컬렉션은 admins/mods에 의해서만 만들어 지므로 어떤 컬렉션도 13 장 미만의 사진을 갖지 않도록 할 수 있습니다. 내가 필요로하는 것은 13 세 이상이 무작위로 사진을 무작위로 선택하는 것입니다.

어떻게하면됩니까?

답변

13

먼저 13 개 임의 관련 사진 ID를 선택할 수 있습니다, 다음 데이터베이스 쿼리를 가져 않습니다

c = Collection.first 
random_ids = c.photo_ids.sort_by { rand }.slice(0, 13) 
@photos = Photo.where(:id => random_ids) 
+0

귀하의 의견에 "최대 13 장의 사진"이 표시됩니다. 정확히 13 장의 사진이 반환됩니까? 적은 돈을 돌려 주면 사용할 수 없습니다. – Andrew

+0

컬렉션에 13 장의 photo_ids가 있으면 13 장의 사진을 반환 할 수 없습니다. 그렇지 않으면, 그렇습니다. –

+0

좋아, 이것을 테스트하고 잘 작동합니다, 감사합니다! – Andrew

6

그냥 SQL에서 랜덤으로 정렬 및 제 13 그렇게 걸릴 :

c.photos.order("RAND()").limit(13) 
+0

SQLite는과 PostgreSQL에서이 작업을 수행 컨트롤러에

module RandomRecordsHelper def random_user_ids(n) user_ids = [] user_count = User.count n.times{user_ids << rand(1..user_count)} return user_ids end 

? SQL로는별로 좋지 않지만 SQL의 차이로 인해 개발 환경과 프로덕션 환경 사이에 과거에 문제가있었습니다. – Andrew

+0

언제든지 시도해 볼 수 있습니다. 나는'RAND()'가 대부분의 SQL 구현에서 작동한다는 것을 확신한다. – tadman

+4

매우 비효율적이며 큰 데이터 세트의 경우 실행하는 데 필요한 것보다 훨씬 오래 걸릴 것이기 때문에 조심하십시오. – nzifnab

-1

여기에 빠른 해결책이 있습니다. 현재 150 만 개가 넘는 레코드와 함께 사용하고 있으며 훌륭한 성능을 얻고 있습니다. 가장 좋은 솔루션은 하나 이상의 임의의 레코드 세트를 캐시 한 다음 원하는 작업자가 원하는 간격으로 새로 고치는 것입니다.

만든 random_records_helper.rb 파일 :

@users = User.where(id: random_user_ids(10)) 
관련 문제