我想为我的模型编写一个类函数,它返回一个满足我条件的随机记录并排除一些记录。我的想法是,我将制作一个“随机文章”。
我希望我的功能看起来像这样
Article.randomArticle([1, 5, 10]) # array of article ids to exclude
一些伪代码:
ids_to_exclude = [1,2,3]
loop do
returned_article = Article.where(published: true).sample
break unless ids_to_exclude.include?(returned_article.id)
do
答案 0 :(得分:1)
让我们看一下DB特定选项。
class Article
# ...
def self.random(limit: 10)
scope = Article.where(published: true)
# postgres, sqlite
scope.limit(limit).order('RANDOM()')
# mysql
scope.limit(limit).order('RAND()')
end
end
Article.random
要求数据库为我们提供10条随机记录。
因此,让我们看看如何添加一个选项来排除某些记录:
class Article
# ...
def self.random(limit: 10, except: nil)
scope = Article.where(published: true)
if except
scope = scope.where.not(id: except)
end
scope.limit(limit).order('RANDOM()')
end
end
现在Article.random(except: [1,2,3])
将获得10条记录,其中id不是[1,2,3]
。
这是因为rails中的.where
返回一个可链的范围。例如:
> User.where(email: 'test@example.com').where.not(id: 1)
User Load (0.7ms) SELECT "users".* FROM "users" WHERE "users"."email" = $1 AND ("users"."id" != $2) [["email", "test@example.com"], ["id", 1]]
=> #<ActiveRecord::Relation []>
我们甚至可以在这里通过一个范围:
# cause everyone hates Bob
Article.random( except: Article.where(author: 'Bob') )
请参阅Rails Quick Tips - Random Records,了解为何DB特定解决方案在这里是一个不错的选择。
答案 1 :(得分:0)
您可以使用以下内容:
ids_to_exclude = [1,2,3,4]
Article.where("published = ? AND id NOT IN (?)", true , ids_to_exclude ).order( "RANDOM()" ).first