2013-05-15 14 views
18

Supponiamo di avere un array di oggetti in Rails @objectsarray in Ruby: Prendere vs Limite vs Prima

Se voglio per visualizzare i primi 5 oggetti, qual è la differenza tra l'utilizzo di:

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

Sto parlando del front end (Ruby), NON SQL. Il motivo per cui gli oggetti non sono limitati in SQL è perché lo stesso array può essere usato altrove senza applicare un limite ad esso.

Ha qualcosa a che fare con l'istanziazione degli oggetti?

+1

Sei sicuro che @objects è una matrice? Non ho mai sentito parlare di un metodo #limit. #prima tuttavia è un metodo standard per restituire il primo elemento. #take è anche un metodo. – seand

+0

Sì '@ objects' è un array. Ho applicato il metodo '# limit' e sembrava che avesse eseguito lo stesso compito di' # take' e '# first'. (Nella vista non il controller). – Prem

+1

@objects non è probabilmente un array ma piuttosto una relazione ActiveRecord. Questo è il motivo per cui usi il limite (5). –

risposta

24
  1. limite non è un metodo matrice
  2. take richiede un argomento; restituisce una matrice vuota se la matrice è vuota.
  3. prima può essere chiamato senza argomento; restituisce nil se l'array è vuoto e l'argomento è assente.

sorgente per prendere 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); 
} 

fonte per 2,0 prima:

   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); 
    } 
} 

In termini di Rails:

  1. limit(5) sarà un dd l'ambito di limit(5) a un ActiveRecord::Relation. Non può essere chiamato su un array, quindi limit(5).limit(4) avrà esito negativo.

  2. first(5) aggiungerà lo scopo di limit(5) a ActiveRecord::Relation. Può anche essere chiamato su un array quindi .first(4).first(3) sarà lo stesso di .limit(4).first(3).

  3. take(5) verrà eseguito la query nell'ambito corrente, costruire tutti gli oggetti e restituire la prima 5. Funziona solo su array, quindi Model.take(5) non funziona, anche se gli altri due funzionerà.

+0

Sei sicuro che '# limit' non è un metodo array? L'ho applicato a una vista su un oggetto array '@ objects' e ha eseguito lo stesso compito di' # take' e '# first'.'# first' può accettare un argomento (facoltativo). Provalo tu stesso – Prem

+0

Sì, guarda le modifiche in termini di binari. –

+0

'take()' può essere chiamato senza argomento. – 0112