Rails 4 default scope
Asked Answered
P

8

74

In my Rails app have a default scope that looks like this:

default_scope order: 'external_updated_at DESC'

I have now upgraded to Rails 4 and, of course, I get the following deprecation warning "Calling #scope or #default_scope with a hash is deprecated. Please use a lambda containing a scope.". I have successfully converted my other scopes but I don't know what the syntax for default_scope should be. This doesn't work:

default_scope, -> { order: 'external_updated_at' }
Premaxilla answered 29/8, 2013 at 8:39 Comment(1)
Related: should default_scope be avoided altogether, and what are some alternative approaches?Blumenthal
S
152

Should be only:

class Ticket < ActiveRecord::Base
  default_scope -> { order(:external_updated_at) } 
end

default_scope accept a block, lambda is necessary for scope(), because there are 2 parameters, name and block:

class Shirt < ActiveRecord::Base
  scope :red, -> { where(color: 'red') }
end
Sydney answered 29/8, 2013 at 8:44 Comment(5)
Thanks for the explanation, Luke. I got a syntax error, then I changed it to default_scope { order('external_updated_at') } and it worked. Can you edit your answer, please, so I can accpet it?Premaxilla
This didn't work for me in 4.0.2 without the arrow. My working solution was default_scope -> { order_by(:created_at => :desc) }Halo
By convention, symbols are preferred when referencing attributes. default_scope { order(:external_updated_at) }Obaza
BTW The correct answer to @JoeGatt question is default_scope order('external_updated_at DESC')Obaza
This does not address ordering if you have results that have varied case (upcase vs. downcase)... any thoughts on ordering via default_scope while forcing downcase?Hildebrandt
D
21

This is what worked for me:

default_scope  { order(:created_at => :desc) }
Durant answered 7/2, 2014 at 9:31 Comment(1)
In new Ruby syntax: default_scope { order(created_at: :desc) }Homologate
G
7

This also worked for me:

default_scope { order('created_at DESC') }

Geulincx answered 21/4, 2014 at 17:54 Comment(0)
M
2

This worked from me (just for illustration with a where) because I came to this topic via the same problem.

default_scope { where(form: "WorkExperience") }
Mcelroy answered 8/10, 2014 at 12:51 Comment(0)
C
2

You can also use the lambda keyword. This is useful for multiline blocks.

default_scope lambda {
  order(external_updated_at: :desc)
}

which is equivalent to

default_scope -> { order(external_updated_at: :desc) }

and

default_scope { order(external_updated_at: :desc) }
Collen answered 26/9, 2016 at 16:30 Comment(0)
A
1

This works for me in Rails 4

default_scope { order(external_updated_at: :desc) }
Annulate answered 30/12, 2014 at 9:48 Comment(0)
A
0
default_scope -> { order(created_at: :desc) }

Don't forget the -> symbol

Antennule answered 25/8, 2016 at 15:29 Comment(0)
L
0
default_scope { 
      where(published: true) 
}

Try This.

Lindsaylindsey answered 7/9, 2016 at 14:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.