8

How would I query all except the first record using ActiveRecord?

Something like...

Item.where(:widget_id => 123).all_but_first

I'm running Rails 3.2.

Shpigford
  • 22,682
  • 52
  • 149
  • 235

5 Answers5

18

I'd do it like this:

Item.where(:widget_id => 123).all[1..-1]
Veraticus
  • 15,378
  • 3
  • 38
  • 44
  • Without creating the ```all_but_first``` method (which would probably just be this exact code) I think this is the easiest and obvious way to handle it. – Caley Woods Mar 08 '12 at 20:12
  • 1
    Note that this will return you an `Array` and not an `ActiveRecord_Relation` – davideghz Jan 05 '18 at 11:23
7

Alternatively you could use offset and limit with a very high limit.

Item.where(:widget_id => 123).limit(18446744073709551610).offset(1)

see Mysql Offset Infinite rows for a discussion on this.

Community
  • 1
  • 1
Volker Pacher
  • 1,677
  • 17
  • 8
1

A little late to the party, but in case this is useful to someone:

  • If you want an array back, I think offset is your best option and most readable.

  • If you want a relation back, you can do: widget.items.where.not(id: widget.items.first.id).

That is assuming you don't care about the order. If you do, you should add that of course.

Alon Dahari
  • 1,099
  • 1
  • 8
  • 24
-1

With scopes this can now be answered exactly

class Item < ApplicationRecord
    scope all_but_first -> { all[1..-1] }
end

But I would advise making sure you know what you mean by 'all but first'. Do you mean the first created, the most recent, the lowest id? When you know that, you can then add the ordering into the scope e.g.

scope :all_but_first, -> { order(created_at: :desc)[1..-1] }
Obromios
  • 11,158
  • 11
  • 58
  • 98
-2

Adding to Veraticus's answer, you can also include the way you want to order the items:

Item.where(:widget_id => 123).order('created_at DESC').all[1..-1]

Happy coding :)

Jean
  • 635
  • 6
  • 16
almawhoob
  • 213
  • 3
  • 4