2011-03-16 2 views
0

레일즈 3의 랜덤 항목에 대한 질문이 있습니다.레일즈 : 여러 범주 내에서 임의의 제품 가져 오기

class Product < ActiveRecord::Base 
    belongs_to :category 

    self.random 
    Product.find :first, :offset => (Product.count * ActiveSupport::SecureRandom.random_number).to_i 
    end 
end 

class Category < ActiveRecord::Base 
    has_many :products 
end 

임의의 오프셋 캐스팅을 사용하여 모든 제품에서 임의의 제품을 int로 가져올 수 있습니다. 그러나 나는 또한 몇몇 주어진 카테고리 내에서 임의의 제품을 얻을 수 있기를 원한다. 나는 이런 식으로 시도했다. 그러나 이것은 오프셋 인덱스 때문에 작동하지 않는다.

class Product < ActiveRecord::Base 
    belongs_to :category 
    self.random cat=["Mac", "Windows"] 
    joins(:categories).where(:categories => { :name => cat }).where(:first, :offset => (Product.count * ActiveSupport::SecureRandom.random_number).to_i) 
    end 
end 

누가 더 나은 해결책을 알고 있는가?

thx! tux

답변

1

당신이 시도하고 단순화 할 수있는이 작은 : 3 당신이 where 절에 전달해야하는 인수의 수를 줄일 수 있습니다 offsetfirst 같은 편리한 도우미 방법을 많이 가지고

class Product < ActiveRecord::Base 
    def self.random(cat = nil) 
    cat ||= %w[ Mac Windows ] 

    joins(:categories).where(:categories => { :name => cat }).offset(ActiveSupport::SecureRandom.random_number(self.count)).first 
    end 
end 

레일

.

일치하는 제품 수가 총 제품 수보다 적은 조인에 문제가있는 경우 ORDER BY RAND()을 사용해야합니다. 실제로 대부분의 경우 거래 실적이 현저히 떨어지는 것은 아니며 언제든지 벤치마킹을 통해 효과를 거둘 수 있습니다.

+0

답장은 Thx입니다. 내가 제품과 카테고리의 거대한 목록을 가지고 있기 때문에 나는 rand()에 의한 주문을 벤치마킹하고 있었고, 그것은 나를 위해 작동하지 않는다. 그래서 그것은 rand()에 의해 너무 느릴 것입니다. 그러나 self.count는 나를 위해 일한다! 고마워! – 23tux

0

오프셋은 주문 이후에 발생하므로 .order ('rand()')를 추가하면 여러 카테고리에서 임의의 요소가 표시됩니다. 순서가 무작위이기 때문에 더 이상 오프셋이 필요 없습니다. 그래서 그냥 :

class Product < ActiveRecord::Base 
    belongs_to :category 
    self.random cat=["Mac", "Windows"] 
    joins(:categories).where(:categories => { :name => cat }).order('rand()').first 
    end 
end 
관련 문제