Я хотел бы указать порядок сортировки по умолчанию в моей модели.
Так что, когда я делаю .where()
без указания, .order()
он использует сортировку по умолчанию. Но если я укажу .order()
, он переопределяет значение по умолчанию.
Я хотел бы указать порядок сортировки по умолчанию в моей модели.
Так что, когда я делаю .where()
без указания, .order()
он использует сортировку по умолчанию. Но если я укажу .order()
, он переопределяет значение по умолчанию.
Ответы:
default_scope
Это работает для Rails 4+:
class Book < ActiveRecord::Base
default_scope { order(created_at: :desc) }
end
Для Rails 2.3, 3 вам нужно это:
default_scope order('created_at DESC')
Для Rails 2.x:
default_scope :order => 'created_at DESC'
Где created_at
находится поле, в котором вы хотите выполнить сортировку по умолчанию.
Примечание: ASC - это код, используемый для Ascending, а DESC - для нисходящего ( desc
, НЕ dsc
!).
scope
Как только вы привыкли к этому, вы также можете использовать scope
:
class Book < ActiveRecord::Base
scope :confirmed, :conditions => { :confirmed => true }
scope :published, :conditions => { :published => true }
end
Для Rails 2 вам нужно named_scope
.
:published
сфера дает вам Book.published
вместо
Book.find(:published => true)
.
Начиная с Rails 3, вы можете «связать» эти методы вместе, объединив их с точками между ними, так что теперь вы можете использовать вышеуказанные области действия Book.published.confirmed
.
С помощью этого метода запрос фактически не выполняется до тех пор, пока не потребуются фактические результаты (ленивая оценка), поэтому 7 областей могут быть объединены в цепочку, но только в результате получится 1 фактический запрос к базе данных, чтобы избежать проблем с производительностью при выполнении 7 отдельных запросов.
Вы можете использовать переданный параметр, такой как date или user_id (что-то, что изменится во время выполнения, и поэтому потребуется эта «ленивая оценка» с лямбда-выражением, например так:
scope :recent_books, lambda
{ |since_when| where("created_at >= ?", since_when) }
# Note the `where` is making use of AREL syntax added in Rails 3.
Наконец, вы можете отключить область по умолчанию с помощью:
Book.with_exclusive_scope { find(:all) }
или даже лучше:
Book.unscoped.all
который отключит любой фильтр (условия) или сортировку (упорядочить по).
Обратите внимание, что первая версия работает в Rails2 +, тогда как вторая (с незаданной областью) предназначена только для Rails3 +
Так что
... если вы думаете, хм, так что это как методы, так ... да, это именно то, что эти области видимости!
Они похожи на рутину, def self.method_name ...code... end
но, как всегда, на ruby - это приятные маленькие синтаксические ярлыки (или «сахар»), которые облегчат вам задачу!
Фактически они являются методами уровня класса, поскольку работают с 1 набором «всех» записей.
Однако их формат меняется, с рельсами 4 появляется предупреждение об устаревании при использовании #scope без прохождения вызываемого объекта. Например, область действия: красный, где (цвет: «красный») следует изменить на scope :red, -> { where(color: 'red') }
.
В качестве примечания, при неправильном использовании сфера по умолчанию может использоваться неправильно.
Это главным образом связано с тем, когда он используется для таких действий, как where
ограничение (фильтрация) выбора по умолчанию ( плохая идея по умолчанию), а не просто для упорядочивания результатов.
Для where
выбора просто используйте обычные именованные области. и добавьте эту область в запрос, например, Book.all.published
где published
это именованная область.
В заключение, области видимости действительно хороши и помогают вам подтолкнуть вещи в модель для подхода DRYer «толстая модель с тонким контроллером».
default_scope { order("#{table_name}.created_at DESC") }
?
default_scope { order(created_at: :desc) }
4.2.6
кажется, updated_at
не сортировать created_at
.
updated_at
по умолчанию? : - |
Быстрое обновление отличного ответа Майкла выше.
Для Rails 4.0+ вы должны поместить свой вид в блок следующим образом:
class Book < ActiveRecord::Base
default_scope { order('created_at DESC') }
end
Обратите внимание, что оператор заказа помещается в блок, обозначенный фигурными скобками.
Они изменили это, потому что было слишком легко передать что-то динамическое (например, текущее время). Это устраняет проблему, потому что блок оценивается во время выполнения. Если вы не используете блок, вы получите эту ошибку:
Поддержка вызова #default_scope без блока удалена. Например, вместо
default_scope where(color: 'red')
, пожалуйста, используйтеdefault_scope { where(color: 'red') }
. (В качестве альтернативы вы можете просто переопределить self.default_scope.)
Как @Dan упоминает в своем комментарии ниже, вы можете использовать более рубиновый синтаксис, например так:
class Book < ActiveRecord::Base
default_scope { order(created_at: :desc) }
end
или с несколькими столбцами:
class Book < ActiveRecord::Base
default_scope { order({begin_date: :desc}, :name) }
end
Спасибо @Dan !
default_scope { order(created_at: :desc) }
будто вы, как и я, пытаетесь минимизировать синтаксис sql в rails. <br/> Если у вас есть несколько столбцов для упорядочения, и вы хотите использовать новый синтаксис, вам может понадобиться обернуть описание столбцы в усы, как этоdefault_scope { order({begin_date: :desc}, :name) }
Вы можете использовать default_scope для реализации порядка сортировки по умолчанию http://api.rubyonrails.org/classes/ActiveRecord/Scoping/Default/ClassMethods.html
default_scope
на этой странице ничего нет , потому что она была реорганизована из ActiveRecord::Base
в ActiveRecord::Scoping::Default::ClassMethods
( api.rubyonrails.org/classes/ActiveRecord/Scoping/Default/… )