Ruby中的数组:Take vs Limit vs First

时间:2013-05-15 01:09:39

标签: ruby-on-rails arrays limit

假设您在Rails @objects

中有一个对象数组

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

  1. @objects.limit(5)
  2. @objects.take(5)
  3. @objects.first(5)
  4. 我说的是前端(Ruby), NOT SQL 。对象在SQL中不受限制的原因是因为可以在别处使用相同的数组而不对其应用限制。

    是否与对象实例化有关?

2 个答案:

答案 0 :(得分:27)

  1. limit不是数组方法
  2. take需要一个论点;如果数组为空,则返回一个空数组。
  3. 首先可以不带参数调用;如果数组为空且参数不存在,则返回nil。
  4. 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)将没有用,虽然其他两个都可以。

答案 1 :(得分:1)

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

    limit上的
  1. ActiveRecord::Relation仍然是Relation。因此,如果您致电:
Model.limit(5).limit(4)

将与:

Model.limit(4)
    first上的
  1. ActiveRecord::Relation将使结果成为Array。因此,您无法在first之后调用任何范围,例如:
Model.first(5).where(id: 1)

但是您可以这样做:

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

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


ActiveRecord::Relation对象上,如果调用first,它将包含ORDER BY 'tables'.id。使用limittake时,不包含ORDER BY,但排序取决于数据库排序实现。