Я хотів би вказати порядок сортування за замовчуванням у своїй моделі.
Так що коли я роблю .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')
Для рейок 2.x:
default_scope :order => 'created_at DESC'
Де created_at
знаходиться поле, на якому потрібно сортувати за замовчуванням сортування.
Примітка: ASC - код, який слід використовувати для висхідного, а DESC - для зменшення ( desc
, НЕ dsc
!).
scope
Коли ви звикли до цього, ви також можете використовувати scope
:
class Book < ActiveRecord::Base
scope :confirmed, :conditions => { :confirmed => true }
scope :published, :conditions => { :published => true }
end
Для Рейки 2 вам потрібно named_scope
.
:published
область дає вам Book.published
замість
Book.find(:published => true)
.
Оскільки Rails 3 ви можете об'єднати ці методи разом, з'єднавши їх з періодами між ними, тож із вищевказаними сферами ви можете тепер використовувати Book.published.confirmed
.
За допомогою цього методу запит фактично не виконується, поки не знадобляться фактичні результати (лінива оцінка), тому 7 областей можна зв'язати разом, але лише в результаті вийде 1 фактичний запит бази даних, щоб уникнути проблем з ефективністю виконання 7 окремих запитів.
Ви можете використовувати переданий параметр, такий як дата або 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
але як завжди з рубіном, вони приємні маленькі синтаксичні ярлики (або "цукор"), щоб зробити вас простішими!
Насправді це методи рівня класу, оскільки вони працюють на 1 наборі записів "усі".
Їх формат змінюється, однак у рейках 4 існує попередження про припинення роботи при використанні #scope без передачі об'єкта, що викликається. Наприклад, область: червоний, де (колір: 'червоний') слід змінити на scope :red, -> { where(color: 'red') }
.
Як бічна примітка, при неправильному використанні _scope за замовчуванням можна неправильно використовувати / зловживати.
В основному це стосується тих випадків, коли він звикає до таких дій, як 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 в рейках. <br/> Якщо у вас є кілька стовпців, які потрібно замовити, і ви хочете використовувати новий синтаксис, можливо, вам знадобиться обгортати desc стовпчиків у вусах, як це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 / ... )