【问题标题】:How to randomize array element positions of an `ActiveRecord::Relation`?如何随机化“ActiveRecord::Relation”的数组元素位置?
【发布时间】:2012-03-14 06:45:36
【问题描述】:

我正在运行 Ruby on Rails 3.2.2,我想随机化 ActiveRecord::Relation 的数组元素位置

我该怎么做?

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3 activerecord random


    【解决方案1】:

    您可以随时将.order('random()') 添加到关系中:

    ar = Model.where(...).where(...).order('random()')
    

    您甚至可以将其添加为范围:

    class Model < ActiveRecord::Base
      scope :randomize, order('random()')
    end
    

    有几点需要注意:

    1. PostgreSQL 和 SQLite 使用 random(),MySQL 使用 rand(),其他数据库我不确定。
    2. ORDER BY random() 在数据库中可能非常昂贵,因此您不想使用它,除非您的 WHERE 子句(即 .where 调用)会限制您将应用 ORDER BY random() 的结果集的大小。李>
    3. .limit 将应用在 ORDER BY 之后,因此 x.limit(n).order('random()') 将 ORDER BY 应用到所有 x,然后在排序后应用 limit(n)。这就是 (2) 中的警告的来源。

    【讨论】:

    • 如果我声明 x.limit(n).order('random()')x.order('random()').limit(n),它是否不同和/或重要(与性能有关)?也就是说,这两个语句是相等的?
    • @Backo:这些是一样的。所有的 AR 关系只是一块一块地构建一个 SQL 查询,所以事情发生的实际顺序完全取决于数据库(即 SQL)是如何做到的。这就是为什么你不想.order('random()'),除非你有一个小桌子或者你的.where()s 将你的结果集限制为一小组行,以及为什么我包括第 (3) 点。
    • BTW:有多少记录被认为是“小集”/“小表”?
    • @Backo: small 取决于您的应用程序和数据库(像往常一样),我可能会称其为小数。
    • 谢谢。我只是想知道什么可以被认为是“小”。
    【解决方案2】:

    鉴于Store.itemshas_many 关系,您可以这样做

    a = store.items.all.shuffle
    

    【讨论】:

    • 此时我无法“尝试”/“运行”您的代码...那么,shuffle 方法是否返回 ActiveRecord::Relation
    • @Backo 不,它将是一个数组。
    • @Backo 我很好奇你为什么要把它保存在ActiveRecord::Relation 中?
    • 很抱歉,因为您可以在上面使用 Ruby on Rails 方法。
    【解决方案3】:

    Client.first.users.sample 呢?

    【讨论】:

    • 你是对的,但是有可能返回一个ActiveRecord::Relation(不是一个Ruby数组)?
    猜你喜欢
    • 2020-07-20
    • 2011-04-18
    • 1970-01-01
    • 1970-01-01
    • 2010-10-23
    • 2021-12-30
    • 2019-02-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多