Ruby中的数组:Take vs Limit vs First

Pre*_*rem 24 arrays ruby-on-rails limit

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

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

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

我在谈论前端(Ruby),而不是SQL.对象不受SQL限制的原因是因为可以在别处使用相同的数组而不对其应用限制.

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

Sha*_*cci 29

  1. limit不是数组方法
  2. 需要一个论点; 如果数组为空,它返回一个空数组.
  3. 首先可以不带参数调用; 如果数组为空且参数不存在,则返回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);
}
Run Code Online (Sandbox Code Playgroud)

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

在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)不起作用,但其他两个将起作用.


小智 6

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

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

    Model.limit(5).limit(4)
    
    Run Code Online (Sandbox Code Playgroud)

    将与:

    Model.limit(4)
    
    Run Code Online (Sandbox Code Playgroud)
  2. firston anActiveRecord::Relation将使结果为Array. 所以你不能在first喜欢之后调用任何范围:

    Model.first(5).where(id: 1)
    
    Run Code Online (Sandbox Code Playgroud)

    但是你可以这样做:

    Model.limit(5).where(id: 1)
    
    Run Code Online (Sandbox Code Playgroud)
  3. take

    Model.take(5)
    
    Run Code Online (Sandbox Code Playgroud)

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


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