25

假设你在 Rails 中有一个对象数组@objects

如果我想显示前 5 个对象,使用有什么区别:

  1. @objects.limit(5)
  2. @objects.take(5)
  3. @objects.first(5)

我说的是前端(Ruby),而不是 SQL。对象在 SQL 中不受限制的原因是因为相同的数组可以在其他地方使用而无需对其施加限制。

它与对象实例化有什么关系吗?

4

2 回答 2

30
  1. limit 不是数组方法
  2. take 需要一个参数;如果数组为空,则返回一个空数组。
  3. first 可以不带参数调用;如果数组为空且参数不存在,则返回 nil。

2.0 的来源

              static VALUE
rb_ary_take(VALUE obj, VALUE n)
{
    long len = NUM2LONG(n);
    if (len < 0) {
        rb_raise(rb_eArgError, "attempt to take negative size");
    }
    return rb_ary_subseq(obj, 0, len);
}

首先是 2.0 的来源:

              static VALUE
rb_ary_first(int argc, VALUE *argv, VALUE ary)
{
    if (argc == 0) {
        if (RARRAY_LEN(ary) == 0) return Qnil;
        return RARRAY_PTR(ary)[0];
    }
    else {
        return ary_take_first_or_last(argc, argv, ary, ARY_TAKE_FIRST);
    }
}

在 Rails 方面:

  1. limit(5)将范围添加limit(5)ActiveRecord::Relation. 它不能在数组上调用,所以limit(5).limit(4)会失败。

  2. first(5)将范围添加limit(5)ActiveRecord::Relation. 它也可以在数组上调用,因此.first(4).first(3).limit(4).first(3).

  3. take(5)将在当前范围内运行查询,构建所有对象并返回前 5 个。 它仅适用于数组,因此Model.take(5)将不起作用,但其他两个将起作用。

于 2013-05-15T01:43:51.937 回答
6

选择的答案似乎已经过时(就 Rails 而言),所以我想更新一些信息。

  1. limiton anActiveRecord::Relation仍将是 a Relation。所以如果你打电话:

    Model.limit(5).limit(4)
    

    将与以下内容相同:

    Model.limit(4)
    
  2. firston anActiveRecord::Relation将使结果为Array. 所以你不能first像这样调用任何范围:

    Model.first(5).where(id: 1)
    

    但是你可以这样做:

    Model.limit(5).where(id: 1)
    
  3. take

    Model.take(5)
    

    现在工作。它将返回一个数组,因此您也不能调用任何数组scope


在一个ActiveRecord::Relation对象上,如果你调用first它,它将包含ORDER BY 'tables'.id. 而with limitand takethere is not ORDER BYincluded,但排序取决于数据库排序实现。

于 2019-06-20T05:10:29.317 回答