Rails: Getting random product within several categories
I have a question about random entries in Rails 3. I have two models:
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
I'm able to get a random product within all products using an random offset castet to int. But I want also be able to get random products WITHIN several given categories. I tried something like this, but this doesn't work, because of the offset index:
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
开发者_C百科end
Anybody here who knows a better solution?
thx! tux
You could try and simplify this a little:
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
Rails 3 has a lot of convenient helper methods like offset
and first
that can reduce the number of arguments you need to pass to the where
clause.
If you're having issues with the join, where the number of products that match is smaller than the number of products in total, you need to use ORDER BY RAND()
instead. It's actually not that huge a deal performance wise in most cases and you can always benchmark to make sure it works for you.
the offset happens after the order, so you can add .order('rand()') then you will be getting random elements from multiple categories. but since the order is random you also do not need offset anymore. so just:
class Product < ActiveRecord::Base
belongs_to :category
self.random cat=["Mac", "Windows"]
joins(:categories).where(:categories => { :name => cat }).order('rand()').first
end
end
精彩评论