ruby 随机ActiveRecord,包含where和排除某些记录

wdebmtf2  于 12个月前  发布在  Ruby
关注(0)|答案(2)|浏览(97)

我想为我的模型写一个类函数,它返回一个满足我的条件的随机记录,并排除一些记录。这个想法是,我将作出一个“随机文章部分。”
我希望我的函数看起来像这样

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
68de4m5k

68de4m5k1#

让我们看看一个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: '[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 Quick Tips - Random Records了解为什么特定于DB的解决方案是一个很好的选择。

slwdgvem

slwdgvem2#

你可以使用一些这样的:

ids_to_exclude = [1,2,3,4]
Article.where("published = ? AND id NOT IN (?)", true , ids_to_exclude ).order( "RANDOM()" ).first

相关问题