带有位置并排除某些记录的随机 ActiveRecord

问题描述 投票:0回答:2

我想为我的模型编写一个类函数,它返回一个满足我的条件的随机记录并排除一些记录。我的想法是,我将制作一个“随机文章部分”。

我希望我的函数看起来像这样

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
ruby-on-rails ruby activerecord
2个回答
2
投票

让我们看一下数据库特定选项。

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: '[email protected]').where.not(id: 1)
User Load (0.7ms)  SELECT "users".* FROM "users" WHERE "users"."email" = $1 AND ("users"."id" != $2)  [["email", "[email protected]"], ["id", 1]]
=> #<ActiveRecord::Relation []>

我们甚至可以在这里传递范围:

# cause everyone hates Bob
Article.random(except: Article.where(author: 'Bob'))

请参阅 Rails 快速提示 - 随机记录,了解为什么数据库特定解决方案是一个不错的选择。


0
投票

你可以使用这样的:

ids_to_exclude = [1,2,3,4]
Article.where("published = ? AND id NOT IN (?)", true , ids_to_exclude ).order( "RANDOM()" ).first
© www.soinside.com 2019 - 2024. All rights reserved.